For this first exercise you will be examining how you can use various software for geospatial analysis and graphical display of spatial data. Because of the variety and availability of operating systems in use today, each of the exercises in this course can be completed in either ArcGIS Pro, QGIS, or R. Each of these software have their pro’s and con’s but for simplicity purposes here is a table that might suggest which software would be best for you:

ArcGIS Pro QGIS R
Available on Windows PC Only Available for PC, Mac, or Linux (limited) Available for PC, Mac, Linux, ChromeOS, iOS, or Android via web modern browser
Available by subscription only Open Source Open Source
Graphical User Interface with built-in functionality for Python; add-ons available for statistical languages Graphical User Interface with built-in functionality for Python; use of plug-ins for other languages and analyses Scripting language, mostly used for statistical purpose; packages expand its use to other applications such as geospatial analyses
Widely used in academia, government, and industry jobs Widely used in academia and industry Predominantly used in academia, research, and specialized industry jobs
Help available at ESRI.com and through various outlets via a google search Help available at QGIS.org and through sites like stackoverflow.com or other sites via google search Help available through individual package documentation and sites like stackoverflow.com or other sites via google search

For the purposes of this course, you can complete the laboratory exercises in any of these software. There will be drop-down menus in every lab color-coded for the three software. Ultimately, you will have access to all of this material during and after the course and while the steps might be different between each version the outcomes will be the same. So if you choose to complete the course with one software you can always go back and complete the work in another software in your own time.

While all of the software will be available on the computers in McCord 210, if you choose to use ArcGIS Pro you will need to contact the APSU GIS Center with your student information to obtain a one year license for your personal computer. QGIS is available for download using this link. If you are completing the course in R you will not need to install any software, however you will need a Google account and access to the Chrome browser. When using R you will be completing all of the lab exercises in the Google Colaboratory and will access everything you need from the exercise pages on GitHub.

More information for each software and the steps to complete this exercise can be found below. Be sure to follow the color-coded drop-down for the specific software you are using for the lab.

View information for ArcGIS Pro

ArcGIS Pro is a proprietary software from ESRI. Student access is available in McCord 210 and several other computer labs on campus. If you wish to obtain the software for use on your personal computer (Windows-based PC only) you will need to contact the APSU GIS Center at 601 N 2nd St, Clarksville, TN 37040, (931) 221-7500. Please have your APSU student ID and A# available for verification prior to obtaining a license. Please contact the GIS Center if you have any issues downloading or installing the software.


View information for QGIS

If you will be using QGIS for the exercises you will need to have the software installed on your computer. QGIS is available for PCs, Mac, and Linux computers. You can find the appropriate download for your operating system here:

When installing on macOS for the first time you may need to go to Systems Preferences > Security and Privacy and on the General tab “Allow apps downloaded from” App Store and identified developers and click Open Anyway. Please contact your instructor if you have any issues downloading or installing the software.


View information for R

You will be completing the R portion of each exercise using the Google Colaboratory Executable Environment. Colaboratory, or “colab” for short, is based on the popular Jupyter Notebooks and allows you to write and execute R or Python in your browser, with:

  • Zero configuration required
  • Free access to GPUs
  • Easy sharing

Each colab notebook is separated into code cells and text cells. A code cell is used to write and execute a script interactively. Each text cell uses simple markdown syntax for creating plain text information. You can easily share the notebook like other Google Drive based documents by clicking the “Share” link in the upper right-hand portion of the window.

Before beginning each exercise using R, you will need to open the Exercise Colab Notebook and alter the URL to view/edit the file in colab. To do this you will navigate to the exercise’s GitHub page; in this case https://github.com/chrismgentry/GIS1-Exercise-2. In the list of folders and files you will find a file that will always be identified as GIS1_EX followed by the exercise number and a .ipynb file extension. So for this exercise it will be GIS1_EX2.ipynb

Finding the Google Colab file on GitHub


When you locate the file, click on the name to open the ipy notebook. In the resulting window, click on the URL and insert tocolab immediately after github in the address. So the new URL for this exercise should now read:
https://githubtocolab.com/chrismgentry/GIS-Exercise-2/blob/main/GIS1_EX2.ipynb

Converting ipy file to colab


Click enter/return and the file should now open inside of Colab. Your screen might have a slightly different appearance, but you should see the Exercise 2, GIS 1 header indicating you are in the correct notebook.

Converting ipy file to colab


Each time you open these colab notebooks, or if you have not interacted with the notebook for an extended period of time, you will need to make sure the environment is connected and all of the sample script has been run. To do this go to Runtime > Run all (or click CRTL+F9) and run the notebook. This may take a moment to complete so be patient until the last code cell has been executed. You should see a green check mark with an allocation of RAM and Disk as shown by horizontal bars which will indicate you are connected. In each section of code there is a Run cell  Run cell button button that will allow you to run the individual code cells. This button will have a rotating loading symbol Run cell button while the code cell is being executed. Once it is complete the box will return to the run state and there may be an output visible depending on the script. You can add your own text or code cells to a notebook simply by moving your cursor slowly over the notebook to reveal the code/text option bar or by going to Insert > Code cell/Text cell.

Adding Text or Code Blocks


By clicking within each code or text cell you can edit the contains and adjust the properties using the various preset option controls.

Edit block properties


You should practice adding and removing cells, editing their content, and rearranging the order of the cells. This will help familiarize you with notebook tools and allow you to manipulate notebooks in these exercises and create your own notebooks in the future.

For each new exercise there will be a colab notebook available. Within the notebook will be sample code for you to run, code cells for you to complete as part of the exercise and questions to be answered within labeled text cells. Detailed directions will be available on the individual exercise webpage. Each completed exercise will have completed code and question sections and the notebook link shared for a grade.

1 The Introduction

The Tennessee Valley Authority (TVA) and Tennessee Department of Environment and Conservation (TDEC) are considering a partnership to increase the number of electric vehicle charging stations across the state. With destinations such as Nashville, Memphis, Gatlinburg and the Great Smoky Mountains, Bristol Motor Speedway, Signal Mountain and the Tennessee Aquarium, tourism is a major part of the state’s economy. So accommodating residents and visitors with electric vehicles as well as creating a network for those traveling the states major interstates (I-65, I-40, I-24, I-75, etc.) is of utmost importance.

TDEC says this network of charging stations will also promote electric vehicle growth by giving drivers confidence they will have easy access to refueling while away from home, eliminating so-called “range anxiety” that keeps many consumers from considering electric vehicles as viable transportation. TVA says electric vehicle adoption will spur jobs and economic investment in the region, keep refueling dollars in the local economy, reduce the regions largest source of carbon emissions, and save drivers and fleets money.

So TVA and TDEC have asked you to develop a map showing the number of public electric vehicle charging stations in the continental United States. This will help them understand what the nations current infrastructure looks like and how Tennessee currently compares to neighboring states. It will also help TVA and TDEC determine approximately how many additional stations they should add.

In this exercise you will:

  • Navigate software used for geospatial analysis
  • Examine attributes of various datasets
  • Learn how to graphically display spatial data
  • Create a cartographically sound product

Software specific directions can be found for each step below. Please submit the answer to the questions and your final map by the due date.

1.1 Step One: The Data

Insert Text Here

View Directions in ArcGIS Pro

Insert Text Here

Question No. 1
Insert Text Here

View Directions in QGIS

The purpose of this exercise is to help familiarize you with the QGIS program. With this software, you will have the ability to view, create, and edit geographic data, query spatial data, examine spatial relationships, and create publishable maps. In these directions I will post images from both PC (on the left) and macOS (on the right) for each step. While your set-up may differ slightly, the configurations and layout of the tools should be similar.

When you begin a new exercise it would be beneficial to create a new folder specifically for the data and project files associated with the lab. This will help you to organize your data and be able to quickly refer back to it in later exercises. For this exercise you will need to download the Electric Vehicle Charging Station data from the GitHub Repository by clicking on the download button at this link and saving it in your exercise folder. Once the download is complete you will need to unzip the file by using Control+click on macOS or right-click > extract all on PC.

Data Download from GitHub


To start the QGIS program press the Start Menu > QGIS or launch the application from the Mac Launchpad. It might be beneficial to create a shortcut on the desktop or add it to your dock for quicker access in the future. As the program loads, the opening screen will be extremely useful to you while working on future projects, however, for this exercise we will select New Empty Project.

QGIS Start Screen


The screen depicted below is separated into two sections. To the left there is the Browser and Layers sections, and on the right is the Map Canvas. Your version may vary slightly from the images. There are a number of ways to add data, but in this example we are going to use the browser window to connect to our ESRI Data folder.

QGIS Start Screen


In the Browser window on the left, navigate to the folder where you saved and unzipped the exercise data folder. Once you locate a folder in folder in the browser, you can use control+click (macOS) or right-click (PC) to Add as a favorite. This will link it to the favorites drop-down in the browser window giving you quicker future access. To add the data, you will navigate to the ev_data.shp file and then click-and-drag it to the map canvas. You will be able to add all types of data in this same way. If there is a pop-up window that mentions transformations go ahead and click OK. While the look of the US in this dataset is less than ideal, the purpose of this exercise is to ensure you know how to display data and basic tools for navigating the software. Transformations will be discussed further in a couple weeks after a lecture on projections and coordinate systems. For now, leave it with option 1 and click OK.

QGIS Start Screen


Your screen should now look similar to the screens below (colors may vary). Notice that the longitude and latitude values at the bottom of the screen adjust as you move your cursor.

QGIS Map Canvas


You can now begin to explore some of the basic tools for navigating the map canvas such as:

  • Zoom in and out with the Fixed Zoom Tools
  • Fixed Zoom Tools
  • Pan tool to postion the map on the screen
  • Pan Tool
  • Map scale where you can adjust the map scale (level of zoom) manually
  • Map Scale
  • Zoom full button which will adjust the view to accommodate all datasets
  • Zoom Full


    Use these tools to zoom in and out, reposition the map on the screen, and return to the current view using the zoom full button.

    Another useful tool is the identify features cursor which uses an icon with a lowercase i in a blue circle Identify Features . This option extracts information for a selected feature from the attribute table of the selected layer.

    Identify Cursor


    If you wanted to view the entire underlying dataset you could control-click (macOS) or right-click (PC) on the active layer and select Open attribute table. In a future exercise you will learn how to sort, query, and edit information within the attribute table. For now, examine the numerous variables available for each state. What is the column name and range of values for the electric vehicle charging stations?
    Hint: This information will be needed in the next section.

    Attribute Table


    Question No. 1
    Using the identify tool, what is the population of Tennessee in 2010? What percentage of the population is female?

    Using the attribute table, find the area (SQMI ) of Colorado. How much larger is it than Wyoming?
    Type your answers in a word document or record the answers on a sheet of paper. They will need to be submitted at the conclusion of this lab.

    View Directions in R

    For each exercise in R you will need to load various packages that are used to complete analyses and graphical output. Generally these packages will be preloaded in the colab notebook however in subsequent labs you may need to install certain packages to complete the exercises. To install a package in R you use the following function where (“x”) is the name of a specific package.

    install.packages("x")

    Once the package has been installed, it will need to be loaded using a similar function:

    library("x")

    In the colab notebook for this exercise you will see where three packages tidyverse, maps, and ggsn were installed and loaded. Now that you have the packages required for the exercise you will need to add the data. For this lab the data consists of state names, abbreviations, and the number of electric vehicle recharing stations. To avoid the need to download the data, you will the read.csv() function and a URL to import the data. Using the head() function will allow you to view the first few lines of any dataset.

    evs <- read.csv('https://raw.githubusercontent.com/chrismgentry/GIS1-Exercise-2/main/Data/ev_stations.csv')
    head(evs)

    In the script above you will see the use of  <-. This is an operator used to create an object that can be used in later steps. If the script was written as read.csv('https://raw.githubusercontent.com/chrismgentry/GIS1-Exercise-2/main/Data/ev_stations.csv') the dataset would have been read and immediately displayed on the screen. However, it would not have been available for subsequent analyses. In colab, you can create your own code block and test it out to see the results. Since you need this information for later, it is important to use  <- to create an object out of the imported data. In this, and future exercises, you will see that operator used frequently to create objects for analysis.

    In order to create a map of electrical vehicle charging stations per state you need to obtain information for the states and create a new object. The tidyverse package is a retainer for a number of individual packages including the Grammar of Graphics or ggplot2 package. This package will frequently be used to display your data, but it also contains geographic information for the US. You can obtain that information by using the map_data function. In a new code block, you can use ?map_data to view help information on the function. Alternatively you can view the documentation for any package or function by searching the package or function name and cran (Comprehensive R Archive Network). For this function you would search map_data cran and the first link is likely to be the RDocumentation page for the function. Within this documentation you will find the arguments available for the function and example scripts. So to create an object that contains information for the continental US you can use:

    us <- map_data('state')

    Using the Grammar of Graphics package, ggplot2, you can create a visualization of this data. Here is that script:

    ggplot(us) + 
      geom_polygon(aes(x=long, y=lat, group=group), color = "white")

    In this script you identified that you wanted to use ggplot to visualize the us object you created in the previous step. Next ggplot needs to know what sort of object to draw. This is done by using the geom_ function followed by a type of geometry. They include point, line, polygon and other geometries such as histograms, boxplots, violin plots for statistics, or contours, rasters, and tiles for three dimensional data. So for this step you used geom_polygon. Next, ggplot needs to know how the data should be displayed. If you create a new code block and type str(us) you can see the structure of the data and a few of the variables. You will notice the dataset contains long (longitude), lat (latitude), group, order, region (the state names), and subregion. So in ggplot you provide a series of aesthetics using aes() to direct ggplot on how to display the data. In this case, x = long, y = lat, and you need to tell it to organize the groups by the category group. If you leave out group for this specific script, ggplot will be unsure what order to draw the polygons and your map will not appear correctly. color = "white" tells ggplot to use white borders for the individual states. What do you think would happen if you change the word color to fill ? In the resulting image, ggplot used the information from your aesthetics to draw the polygons and automate labels for the x and y axes. In a later step you will learn how to customize those labels.

    It may seem as if this is a difficult way to view the data. In other software with a graphical user interface (GUI) you would most likely click open, navigate to the folder containing the data, double-click on that dataset, and then it would appear on your screen. Essentially, every time you click “open” on a GUI interface, it is executing a specific set of scripts to 1.) open the navigation window, 2.) allow the selected file to be imported, and 3.) then display the information on your screen. What you did above in three lines of code was to tell ggplot to 1.) create an object called us and 2.) display it on the screen with some specific parameters. The benefit of completing this in R versus something with a GUI interface is, if you had three more similar datasets to view, you would simply change US to another object and re-run the script. To repeat the process in a GUI interface you would need to repeat all of the steps from the beginning. This might not seem like much for three steps, but what if your visualization had twenty steps, as many do? In R you would still simply change the dataset and run the same script, but in other programs you would need to repeat the same twenty steps for each dataset. Additionally, if a colleague wanted to display some data in the same way, you can either copy and paste the code or type out each of the twenty steps with directions. Which of these seems to be more consistently repeatable? Once you begin to understand the syntax (order or arrangement of words and phrases to form proper scripts) you will be more easily able to interpret sample scripts and fix errors in your own code.

    Question No. 1
    You used ggplot(us) + geom_polygon(aes(x=long, y=lat, group=group), color = "white") to create the visualization in this step. What script would you use to make the same map but with black borders and blue states? Add a code cell below this one, type the script, and run it to view the output. Hint: color = “…..”, fill = “…..”

    1.2 Step Two: The Analysis

    In this step you will organize and display the data in order to prepare it for the final visualization.

    View Directions in ArcGIS Pro

    Insert Text Here


    View Directions in QGIS

    Now that you have the data displayed on the screen and understand how to access the underlying data, you need to customize the view so you can see the spatial distribution of electric vehicle charging stations in the US. To begin you will need to control-click (macOS) or right-click (PC) on the ev_data in your layers and click on properties.

    Right Click Properties


    In the resulting window you will need to go to the Symbology tab (1.) in the left-hand menu. In this window you can change the fill of the polygons and change their opacity (or level of transparency). You can also adjust the symbology of your dataset. Those options are available in a selection bar at the top of the window. For this dataset they are:

  • No Symbol
  • No Symbols
  • Single Symbol
  • Single Symbol
  • Categorized
  • Categorized Symbols
  • Graduated
  • Graduated Symbols
  • Rule-based
  • Rule Based Symbols
  • Inverted Polygons
  • Inverted Polygon Symbols
  • 2.5 D
  • 2.5 D Symbols


    For this specific data you will choose Graduated (2.) since the data needs to be displayed by a range of numeric values. Next you will select the ev_station variable (3.) in the dataset. In the drop-down for the Color ramp option you have a number of color options to choose. For this example select Viridis (4.). Do you recall what the range of values for the ev_station data? Because the largest value is greater than 30,000 and the smallest value is around 100, you will need to set the Mode to a logarithmic scale (5.) to properly display the data while avoiding a bias of the larger values. Change the Classes to 6 (6.) and click OK (7.).

    Symbology Properties

    Because the macOS and PC versions are identical only one image is shown.


    Your screen should now look similar to this:

    Graduated Data

    At this point you should save your work. Whether using macOS or PC, on the menu bar go to Project > Save As… and save your project in the folder you create for this exercise.

    Question No. 2
    In this step you used a Graduated symbology to visualize the data and organized the values logarithmically. There were several other options within mode menu.

  • Equal Count (Quantile)
  • Equal Count
  • Equal Interval
  • Equal Interval
  • Logarithmic Scale
  • Logarithmic Scale
  • Natural Breaks (Jenks)
  • Natural BReaks (Jenks)
  • Pretty Breaks
  • Pretty Breaks
  • Standard Deviation
  • Standard Deviation
    Adjusting the mode value, describe how the visualization changes with each of these different options.
    Record your answers and submit at the conclusion of the lab.

    View Directions in R

    Now that you have datasets for electric vehicle charging stations (object = evs) and the continental US (object = us), you need to combined that data to allow for the states to be color coded based on the number of charging stations per state. To do this you will use a function called merge from the base R functions that will allow you to combine the information from the evs and us into a single dataset that contains information from both based on a common variable. So to start you will need to determine what variable(s) are contained within each dataset. You have seen how to examine datasets using both head() and str() already in this exercise. Create a new code block and examine the structure of each dataset. You will see that there is a column for state name in each except they are labeled differently. This is important information you will need to properly merge the datasets.

    To do this you will first create an object (<-) with a new name, then with the merge function set the following arguments:

    • x, which is the first data set
    • y, which is the second dataset
    • by.x, identifies the column to use for the merge in x
    • by.y, identifies the column to use for the merge in y
    • all = TRUE, which tells the function to retain all data

    So your final script will be:

    states <- merge(x = us, y = evs, by.x = "region", by.y = "state", all = TRUE)
    head(states)

    Now you will see the columns for evs and abbreviation included in the us dataset. This new dataset will be what you use to visualize the information in the next step.

    Question No. 2
    Using sum(states) in a new code cell, what are the largest and smallest number of electric vehicle charging stations?

    1.3 Step Three: The Visualization

    You will learn how to create a graphical display of your data that includes cartographic elements such as legend, scale bar, north arrow, etc.

    View directions in ArcGIS Pro

    Insert Text Here


    View directions in QGIS

    Now it’s time to turn your data into a map. From the menu bar in either macOS or PC click Program > New Print Layout. This will open a new window where you will add the data, title, legend, north arrow, scale bar, and your name and date.

    New Print Layout


    View directions in R

    With this new dataset you are now ready to create a map to examine the distribution of electric vehicle charging stations across the country. In the step one you used a very simple script to display the us data.

    ggplot(us) + 
      geom_polygon(aes(x=long, y=lat, group=group), color = "white")

    A similar script would allow you to quickly visualize the data ggplot(states) + geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white"), however, you need to add a number of elements in order to create a map such as a scale bar, north arrow, title, etc. Additionally, you can customize other components to provide a better overall visualization.

    Earlier in the notebook we installed the ggsn package. This package allows you to add “north symbols and scale bars for maps created with ‘ggplot2’ or ‘ggmap’.” So you can build on the script above to create a map of the information in the states dataset. To begin, run the script above with the added fill argument to see the outcome:

    ggplot(states) + geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white")

    One thing you will notice is that the categories are very difficult to distinguish. Because you have wide ranging data in the evs_count column only the largest value is showing. A simple fix to this would be to take the common logarithm of the data to standardize the data by removing the skewness towards large values. The function scale-viridis scales the data and provides a color map designed to be perceived by viewers with common forms of color blindness. So you can add scale_fill_viridis_c(option = "D", trans = "log10") to the script above where:

    • scale_fill_viridis_c is a fill pattern for continuous data
    • option = “D” is the default color option
      • There are five color options available with this function
        • A = magma
        • B = inferno
        • C = plasma
        • D = viridis
        • E = cividis
    • trans = “log10” transforms the data using common logarithm, other options are available; see documentation

    The new script should now look like this:

    ggplot(states) + 
      geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white") +
      scale_fill_viridis_c(option = "D", trans = "log10")

    Now that you are able to visualize the separations in the data you can add additional information. You can start with customizing the labels, map title, and legend title. This can all be completed by adding a single line of code containing all of the text information for those items:

    ggplot(states) + 
        geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white") +
      scale_fill_viridis_c(option = "D", trans = "log10") + 
      labs(x="Longitude",y="Latitude", title="Number of Electric Vehicle Charging Stations Per State", fill = "No. of Stations")

    Feel free to edit the label names and the color option in the script to provide your own customizations. Next you need to add a scale bar and north arrow. To view the available options for the north arrow type northSymbols() into a new code block. The numeric values below each symbol will be used in the script to identify the specific style you choose. Because the north arrow, north, is specifically related to the map data you need to provide the following arguments:

    • dataset
    • symbol, identified by the numerical value from northSymbols()
    • location, indicating where to base the location on the map
    • anchor, coordinates for the symbol position on the map (based off the location)
    • scale, the symbol size as a proportion of the map size

    So your new script will look like:

    ggplot(states) + 
      geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white") +
      scale_fill_viridis_c(option = "D", trans = "log10") + 
      labs(x="Longitude",y="Latitude", title="Number of Electric Vehicle Charging Stations Per State", fill = "No. of Stations") +
      north(states, location = "bottomleft", scale = 0.05, symbol = 12, anchor = c(x= -70, y= 25))

    In this example, location = "bottomleft" means the location of the north arrow will be based from the bottom left of the symbol and ``anchor = c(x = -70, y = 25)``` is the geographic location on the map to draw the symbol. For example, if the anchors were set at -100 and 40 the symbol would be draw on the Nebraska/Kansas border. Feel free to adjust the anchor points to draw the north arrow in your preferred location.

    Now you need to add a scale bar. Many of the arguments used for the north arrow are duplicated for scalebar

    • dataset
    • location, indicating where to base the location on the map
    • anchor, coordinates for the symbol position on the map (based off the location)
    • distance for each unit of the scale bar
    • unit of measurement such as mi, km, etc.
    • transform (TRUE/FALSE), assumes the coordinates are in decimal degrees
    • model, choice of ellipsoid; which will be discussed later in the semester
    • st.size, scale bar size
    • st.dist, distance between the scale bar and the scale bar’s text, as a proportion of the y axis
    ggplot(states) + 
      geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white") +
      scale_fill_viridis_c(option = "D", trans = "log10") + 
      labs(x="Longitude",y="Latitude", title="Number of Electric Vehicle Charging Stations Per State", fill = "No. of Stations") +
      north(states, location = "bottomleft", scale = 0.05, symbol = 12, anchor = c(x= -70, y= 25)) + 
      scalebar(states, dist = 250, dist_unit = "mi", transform = TRUE, model = "WGS84", location = "bottomleft", st.dist = 0.05, st.size = 2, anchor = c(x=-125,y=27))

    As with all of the other customizations above, feel free to adjust the units, distance, text distance, and size based on your own style.

    Finally, you will need to add text to the map to indicate the name of the person who created the map and the date. In the future you will possibly include references or other text based information. There are a number of different ways you will explore for adding text information to your maps, such as caption = in labs, but for this example you will use annotate(). Similar to the north arrow and scale bar, there will be a

    • x and y argument to set the location
    • size to indicate the font size
    • label for the text you wish to include; to create a character return to move text to a new line you should use “\n” where you want the text to move to a new line

    Your final script should now look similar to this:

    ggplot(states) + 
      geom_polygon(aes(x=long, y=lat, group=group, fill = evs_count), color = "white") +
      scale_fill_viridis_c(option = "D", trans = "log10") + 
      labs(x="Longitude",y="Latitude", title="Number of Electric Vehicle Charging Stations Per State", fill = "No. of Stations") +
      north(states, location = "bottomleft", scale = 0.05, symbol = 12, anchor = c(x= -70, y= 25)) + 
      scalebar(states, dist = 250, dist_unit = "mi", transform = TRUE, model = "WGS84", location = "bottomleft", st.dist = 0.05, st.size = 2, anchor = c(x=-125,y=27)) +
      annotate("text", x = -90, y = 25, label = "Your Name \n The Date", size = 2)

    There is an exhaustive amount of modifications that can be applied to the map above, but for now you have the minimum information required to create a map of similar kinds of data. In future exercises you will use various function to customize the look of your maps.

    Question No. 3
    How does the dist =  argument in the scalebar function relate specifically to the distance of the scale bar on your map? How would changing the value alter the appearance?

    1.4 Step Four: Your Turn

    After a rash of severe weather over the past few years the Montgomery County Emergency Management Agency has asked you to provide a map detailing the number of reported tornadoes in each Tennessee county over the past several decades. This information will be shared with neighboring counties in middle Tennessee as a part of severe weather education campaign designed to inform communities about the risk of tornadoes in the region. The map should include all of the elements included on your previous map of electric vehicle charging stations such as:

    • Title
    • Scale
    • North Arrow
    • Legend
    • Name/Date of Cartographer

    Software specific directions can be found for each step below. Please submit the answer to the questions you answered above as well as your final tornado map by the due date.

    View directions in ArcGIS Pro

    Insert Text Here


    View directions in QGIS

    Insert Text Here


    View directions in R

    This portion of the exercise is meant to reinforce the skills you learned in the part of the lab. The steps you will take to complete your final map will be to:

    1. Create an object from the tornadoes dataset
    2. Obtain a dataset of Tennessee counties
    3. Determine which columns can be used to merge the datasets
    4. Map out the data using ggplot

    To begin the exercise you will need this URL to the comma delimited dataset:

    https://raw.githubusercontent.com/chrismgentry/GIS1-Exercise-2/main/Data/tn_tornadoes.csv

    This data represents the number of reported tornadoes in each county from 1950-2020. As in step one of the exercise, you can use the <- operator to create a new object and the read.csv() function with the link to the dataset to import the data. Remember you can use head() or str() to examine the information.

    To obtain county information for the State of Tennessee you should use the following script:

    tn <- map_data('county', region = "tennessee")

    If you search for map_data in the ggplot2 documentation you will find an example of a script used to isolate information for the State of Iowa that can be adapted for any state in the dataset. Remember when working with scripts, Google is your friend! All it requires is asking the correct question to find some example code online that can help guide you. There are numerous possible answers to the same problem so don’t hesitate to try other methods.

    Using the example code from step two, you will need to merge the two datasets into a new object based on a common variable such as Hint…hint county name.

    Finally, by adapting the ggplot code in step four, you can map the information for tornado_count for each county in Tennessee. In order to limit the scope of your map to just the state you should add the following script to your modified ggplot code from above:

    coord_fixed(xlim = c(-90,-82), ylim = c(35, 37))

    The coord_fixed() function limits the axes based on specified values. The values are based on the units of measure of the data. In this can you see where the x axis is limited (xlim) from -82° to -90° west longitude and the y axis is limited (ylim) from 35° to 37° north latitude. If you omit this script your map will likely have a “smashed” appearance. For creating maps in R it is generally advisable to set the x and y coordinates to ensure proper display of your data. Remember you will need to adjust the anchor points of your name and date text, north arrow and scale bar to fit the current map view. Additionally, the title and legend text should also reflect the information depicted on your map.

    Question No. 4
    Which county had the highest number of reported tornadoes?
    Type subset(tn_tornadoes, tornado_count == max(tornado_count)) into a new code cell or use Google to search for a county map of Tennessee to determine county locations on your map.
    Hint: Replace tn_tornadoes in the code above with the object you created by merging the tornado and counties datasets.

    2 The Write-Up

    The Montgomery County Emergency Management Agency has asked you to provide a map detailing the number of reported tornadoes in each Tennessee county over the past several decades. Based on the map you create above, complete a lab write-up that addresses the following questions:

    • Provide the names of the five (5) counties that recorded the most tornadoes during that time frame
    • Describe which regions of Tennessee had the fewest reported tornadoes
    • Inform MCEMA which metropolitan regions could be most impacted by future severe weather events

    When complete, send link to your Colab Notebook via email.

    LS0tDQp0aXRsZTogIkV4ZXJjaXNlIDI6IEdldHRpbmcgdG8ga25vdy4uLiA8YnI+PHNtYWxsPkdlb2dyYXBoaWMgSW5mb3JtYXRpb24gU3lzdGVtcyAxIExhYjwvc21hbGw+PC9icj4iDQphdXRob3I6ICJHRU9HIDMxNTAiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogICAgcm93cy5wcmludDogMTANCiAgICB0aGVtZTogY29zbW8NCiAgICBoaWdobGlnaHQ6IGJyZWV6ZWRhcmsNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KICAgICAgc21vb3RoX3Njcm9sbDogeWVzDQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQplZGl0b3Jfb3B0aW9uczoNCiAgY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQ0KICBtb2RlOiBnZm0NCi0tLQ0KDQpgYGB7PWh0bWx9DQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KDQpoMS50aXRsZSB7DQogIGZvbnQtc2l6ZTogNDBweDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuYXV0aG9yIHsgLyogSGVhZGVyIDQgLSBhbmQgdGhlIGF1dGhvciBhbmQgZGF0YSBoZWFkZXJzIHVzZSB0aGlzIHRvbyAgKi8NCiAgZm9udC1zaXplOiAyMHB4Ow0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgY29sb3I6IERhcmtCbHVlOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQoNCi56b29tIHsNCiAgdHJhbnNpdGlvbjogdHJhbnNmb3JtIC4yczsgLyogQW5pbWF0aW9uICovDQogIG1hcmdpbjogMCBhdXRvOw0KfQ0KLnpvb20gaW1new0KCXdpZHRoOjEwMCU7DQoJaGVpZ2h0OmF1dG87CQ0KfQ0KLnpvb206aG92ZXIgew0KICB0cmFuc2Zvcm06IHNjYWxlKDIpOw0KfQ0KDQo8L3N0eWxlPg0KYGBgDQoNCjxocj48L2hyPg0KDQpGb3IgdGhpcyBmaXJzdCBleGVyY2lzZSB5b3Ugd2lsbCBiZSBleGFtaW5pbmcgaG93IHlvdSBjYW4gdXNlIHZhcmlvdXMgc29mdHdhcmUgZm9yIGdlb3NwYXRpYWwgYW5hbHlzaXMgYW5kIGdyYXBoaWNhbCBkaXNwbGF5IG9mIHNwYXRpYWwgZGF0YS4gQmVjYXVzZSBvZiB0aGUgdmFyaWV0eSBhbmQgYXZhaWxhYmlsaXR5IG9mIG9wZXJhdGluZyBzeXN0ZW1zIGluIHVzZSB0b2RheSwgZWFjaCBvZiB0aGUgZXhlcmNpc2VzIGluIHRoaXMgY291cnNlIGNhbiBiZSBjb21wbGV0ZWQgaW4gZWl0aGVyICoqW0FyY0dJUyBQcm9de3N0eWxlPSJjb2xvcjojZmY0NTAwIn0qKiwgKipbUUdJU117c3R5bGU9ImNvbG9yOiAjMDA2NDAwIn0qKiwgb3IgKipbUl17c3R5bGU9ImNvbG9yOiAjNjQ5NUVEIn0qKi4gRWFjaCBvZiB0aGVzZSBzb2Z0d2FyZSBoYXZlIHRoZWlyIHBybydzIGFuZCBjb24ncyBidXQgZm9yIHNpbXBsaWNpdHkgcHVycG9zZXMgaGVyZSBpcyBhIHRhYmxlIHRoYXQgbWlnaHQgc3VnZ2VzdCB3aGljaCBzb2Z0d2FyZSB3b3VsZCBiZSBiZXN0IGZvciB5b3U6DQoNCnwgW0FyY0dJUyBQcm9de3N0eWxlPSJjb2xvcjojZmY0NTAwIn0gfCBbUUdJU117c3R5bGU9ImNvbG9yOiAjMDA2NDAwIn0gfCBbUl17c3R5bGU9ImNvbG9yOiAjNjQ5NUVEIn0gfA0KfCAtLS0gfCAtLS0gfCAtLS0gfA0KfCBBdmFpbGFibGUgb24gPHU+V2luZG93cyBQQyBPbmx5PC91PiB8IEF2YWlsYWJsZSBmb3IgUEMsIE1hYywgb3IgTGludXggKGxpbWl0ZWQpIHwgQXZhaWxhYmxlIGZvciBQQywgTWFjLCBMaW51eCwgQ2hyb21lT1MsIGlPUywgb3IgQW5kcm9pZCB2aWEgd2ViIG1vZGVybiBicm93c2VyfA0KfCBBdmFpbGFibGUgYnkgc3Vic2NyaXB0aW9uIG9ubHkgfCBPcGVuIFNvdXJjZSB8IE9wZW4gU291cmNlIHwNCnwgR3JhcGhpY2FsIFVzZXIgSW50ZXJmYWNlIHdpdGggYnVpbHQtaW4gZnVuY3Rpb25hbGl0eSBmb3IgUHl0aG9uOyBhZGQtb25zIGF2YWlsYWJsZSBmb3Igc3RhdGlzdGljYWwgbGFuZ3VhZ2VzIHwgR3JhcGhpY2FsIFVzZXIgSW50ZXJmYWNlIHdpdGggYnVpbHQtaW4gZnVuY3Rpb25hbGl0eSBmb3IgUHl0aG9uOyB1c2Ugb2YgcGx1Zy1pbnMgZm9yIG90aGVyIGxhbmd1YWdlcyBhbmQgYW5hbHlzZXMgfCBTY3JpcHRpbmcgbGFuZ3VhZ2UsIG1vc3RseSB1c2VkIGZvciBzdGF0aXN0aWNhbCBwdXJwb3NlOyBwYWNrYWdlcyBleHBhbmQgaXRzIHVzZSB0byBvdGhlciBhcHBsaWNhdGlvbnMgc3VjaCBhcyBnZW9zcGF0aWFsIGFuYWx5c2VzIHwNCnwgV2lkZWx5IHVzZWQgaW4gYWNhZGVtaWEsIGdvdmVybm1lbnQsIGFuZCBpbmR1c3RyeSBqb2JzIHwgV2lkZWx5IHVzZWQgaW4gYWNhZGVtaWEgYW5kIGluZHVzdHJ5IHwgUHJlZG9taW5hbnRseSB1c2VkIGluIGFjYWRlbWlhLCByZXNlYXJjaCwgYW5kIHNwZWNpYWxpemVkIGluZHVzdHJ5IGpvYnMgfA0KSGVscCBhdmFpbGFibGUgYXQgW0VTUkkuY29tXShodHRwczovL3Byby5hcmNnaXMuY29tL2VuL3Byby1hcHAvbGF0ZXN0L2hlbHAvbWFpbi93ZWxjb21lLXRvLXRoZS1hcmNnaXMtcHJvLWFwcC1oZWxwLmh0bSkgYW5kIHRocm91Z2ggdmFyaW91cyBvdXRsZXRzIHZpYSBhIGdvb2dsZSBzZWFyY2ggfCBIZWxwIGF2YWlsYWJsZSBhdCBbUUdJUy5vcmddKGh0dHBzOi8vZG9jcy5xZ2lzLm9yZy8zLjE2L2VuL2RvY3MvdXNlcl9tYW51YWwvKSBhbmQgdGhyb3VnaCBzaXRlcyBsaWtlIHN0YWNrb3ZlcmZsb3cuY29tIG9yIG90aGVyIHNpdGVzIHZpYSBnb29nbGUgc2VhcmNoIHwgSGVscCBhdmFpbGFibGUgdGhyb3VnaCBpbmRpdmlkdWFsIHBhY2thZ2UgW2RvY3VtZW50YXRpb25dKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9hdmFpbGFibGVfcGFja2FnZXNfYnlfbmFtZS5odG1sKSBhbmQgc2l0ZXMgbGlrZSBzdGFja292ZXJmbG93LmNvbSBvciBvdGhlciBzaXRlcyB2aWEgZ29vZ2xlIHNlYXJjaA0KDQpGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgY291cnNlLCB5b3UgY2FuIGNvbXBsZXRlIHRoZSBsYWJvcmF0b3J5IGV4ZXJjaXNlcyBpbiBhbnkgb2YgdGhlc2Ugc29mdHdhcmUuIFRoZXJlIHdpbGwgYmUgZHJvcC1kb3duIG1lbnVzIGluIGV2ZXJ5IGxhYiBjb2xvci1jb2RlZCBmb3IgdGhlIHRocmVlIHNvZnR3YXJlLiBVbHRpbWF0ZWx5LCB5b3Ugd2lsbCBoYXZlIGFjY2VzcyB0byBhbGwgb2YgdGhpcyBtYXRlcmlhbCBkdXJpbmcgYW5kIGFmdGVyIHRoZSBjb3Vyc2UgYW5kIHdoaWxlIHRoZSBzdGVwcyBtaWdodCBiZSBkaWZmZXJlbnQgYmV0d2VlbiBlYWNoIHZlcnNpb24gdGhlIG91dGNvbWVzIHdpbGwgYmUgdGhlIHNhbWUuIFNvIGlmIHlvdSBjaG9vc2UgdG8gY29tcGxldGUgdGhlIGNvdXJzZSB3aXRoIG9uZSBzb2Z0d2FyZSB5b3UgY2FuIGFsd2F5cyBnbyBiYWNrIGFuZCBjb21wbGV0ZSB0aGUgd29yayBpbiBhbm90aGVyIHNvZnR3YXJlIGluIHlvdXIgb3duIHRpbWUuDQoNCldoaWxlIGFsbCBvZiB0aGUgc29mdHdhcmUgd2lsbCBiZSBhdmFpbGFibGUgb24gdGhlIGNvbXB1dGVycyBpbiBNY0NvcmQgMjEwLCBpZiB5b3UgY2hvb3NlIHRvIHVzZSAqKltBcmNHSVMgUHJvXXtzdHlsZT0iY29sb3I6I2ZmNDUwMCJ9KiogeW91IHdpbGwgbmVlZCB0byBjb250YWN0IHRoZSBBUFNVIEdJUyBDZW50ZXIgd2l0aCB5b3VyIHN0dWRlbnQgaW5mb3JtYXRpb24gdG8gb2J0YWluIGEgb25lIHllYXIgbGljZW5zZSBmb3IgeW91ciBwZXJzb25hbCBjb21wdXRlci4gKipbUUdJU117c3R5bGU9ImNvbG9yOiAjMDA2NDAwIn0qKiBpcyBhdmFpbGFibGUgZm9yIGRvd25sb2FkIHVzaW5nIHRoaXMgKipbbGlua10oaHR0cHM6Ly9xZ2lzLm9yZy9lbi9zaXRlL2ZvcnVzZXJzL2Rvd25sb2FkLmh0bWwpe3N0eWxlPSJjb2xvcjogIzAwNjQwMCJ9KiouIElmIHlvdSBhcmUgY29tcGxldGluZyB0aGUgY291cnNlIGluICoqW1Jde3N0eWxlPSJjb2xvcjogIzY0OTVFRCJ9KiogeW91IHdpbGwgbm90IG5lZWQgdG8gaW5zdGFsbCBhbnkgc29mdHdhcmUsIGhvd2V2ZXIgeW91IHdpbGwgbmVlZCBhIFtHb29nbGUgYWNjb3VudF0oaHR0cHM6Ly9hY2NvdW50cy5nb29nbGUuY29tL3NpZ251cC92Mi93ZWJjcmVhdGVhY2NvdW50KSBhbmQgYWNjZXNzIHRvIHRoZSBbQ2hyb21lIGJyb3dzZXJdKGh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vY2hyb21lLykuIFdoZW4gdXNpbmcgKipbUl17c3R5bGU9ImNvbG9yOiAjNjQ5NUVEIn0qKiB5b3Ugd2lsbCBiZSBjb21wbGV0aW5nIGFsbCBvZiB0aGUgbGFiIGV4ZXJjaXNlcyBpbiB0aGUgW0dvb2dsZSBDb2xhYm9yYXRvcnldKGh0dHBzOi8vY29sYWIucmVzZWFyY2guZ29vZ2xlLmNvbS8pIGFuZCB3aWxsIGFjY2VzcyBldmVyeXRoaW5nIHlvdSBuZWVkIGZyb20gdGhlIGV4ZXJjaXNlIHBhZ2VzIG9uIF9HaXRIdWJfLg0KDQpNb3JlIGluZm9ybWF0aW9uIGZvciBlYWNoIHNvZnR3YXJlIGFuZCB0aGUgc3RlcHMgdG8gY29tcGxldGUgdGhpcyBleGVyY2lzZSBjYW4gYmUgZm91bmQgYmVsb3cuIEJlIHN1cmUgdG8gZm9sbG93IHRoZSBjb2xvci1jb2RlZCBkcm9wLWRvd24gZm9yIHRoZSBzcGVjaWZpYyBzb2Z0d2FyZSB5b3UgYXJlIHVzaW5nIGZvciB0aGUgbGFiLiANCg0KPGRldGFpbHM+DQo8c3VtbWFyeT48YmlnPlZpZXcgaW5mb3JtYXRpb24gZm9yIDxiPiBbQXJjR0lTIFByb117c3R5bGU9ImNvbG9yOiNmZjQ1MDAifSA8L2I+PC9iaWc+PC9zdW1tYXJ5Pg0KDQo8Yj5bQXJjR0lTIFByb117c3R5bGU9ImNvbG9yOiNmZjQ1MDAifTwvYj4gaXMgYSBwcm9wcmlldGFyeSBzb2Z0d2FyZSBmcm9tIFtFU1JJXShodHRwczovL3d3dy5lc3JpLmNvbS9lbi11cy9ob21lKS4gU3R1ZGVudCBhY2Nlc3MgaXMgYXZhaWxhYmxlIGluIE1jQ29yZCAyMTAgYW5kIHNldmVyYWwgb3RoZXIgY29tcHV0ZXIgbGFicyBvbiBjYW1wdXMuIElmIHlvdSB3aXNoIHRvIG9idGFpbiB0aGUgc29mdHdhcmUgZm9yIHVzZSBvbiB5b3VyIHBlcnNvbmFsIGNvbXB1dGVyIChXaW5kb3dzLWJhc2VkIFBDIG9ubHkpIHlvdSB3aWxsIG5lZWQgdG8gY29udGFjdCB0aGUgW0FQU1UgR0lTIENlbnRlcl0oaHR0cHM6Ly93d3cuYXBzdWdpcy5vcmcvKSBhdCA2MDEgTiAybmQgU3QsIENsYXJrc3ZpbGxlLCBUTiAzNzA0MCwgKDkzMSkgMjIxLTc1MDAuIFBsZWFzZSBoYXZlIHlvdXIgQVBTVSBzdHVkZW50IElEIGFuZCBBIyBhdmFpbGFibGUgZm9yIHZlcmlmaWNhdGlvbiBwcmlvciB0byBvYnRhaW5pbmcgYSBsaWNlbnNlLiBQbGVhc2UgY29udGFjdCB0aGUgR0lTIENlbnRlciBpZiB5b3UgaGF2ZSBhbnkgaXNzdWVzIGRvd25sb2FkaW5nIG9yIGluc3RhbGxpbmcgdGhlIHNvZnR3YXJlLg0KDQo8L2RldGFpbHM+DQo8aHI+PC9ocj4NCg0KPGRldGFpbHM+DQo8c3VtbWFyeT48YmlnPlZpZXcgaW5mb3JtYXRpb24gZm9yIDxiPiBbUUdJU117c3R5bGU9ImNvbG9yOiAjMDA2NDAwIn0gPC9iPjwvYmlnPjwvc3VtbWFyeT4NCg0KSWYgeW91IHdpbGwgYmUgdXNpbmcgPGI+W1FHSVNde3N0eWxlPSJjb2xvcjogIzAwNjQwMCJ9PC9iPiBmb3IgdGhlIGV4ZXJjaXNlcyB5b3Ugd2lsbCBuZWVkIHRvIGhhdmUgdGhlIHNvZnR3YXJlIGluc3RhbGxlZCBvbiB5b3VyIGNvbXB1dGVyLiAqKlFHSVMqKiBpcyBhdmFpbGFibGUgZm9yIFBDcywgTWFjLCBhbmQgTGludXggY29tcHV0ZXJzLiBZb3UgY2FuIGZpbmQgdGhlIGFwcHJvcHJpYXRlIGRvd25sb2FkIGZvciB5b3VyIG9wZXJhdGluZyBzeXN0ZW0gaGVyZToNCg0KLSBbUEMgdmVyc2lvbiwgMy4xNl0oaHR0cHM6Ly9xZ2lzLm9yZy9kb3dubG9hZHMvUUdJUy1PU0dlbzRXLTMuMTYuNi0xLVNldHVwLXg4Nl82NC5leGUpDQotIFttYWNPUyB2ZXJzaW9uLCAzLjE2XShodHRwczovL3FnaXMub3JnL2Rvd25sb2Fkcy9tYWNvcy9xZ2lzLW1hY29zLWx0ci5kbWcpDQotIFtMaW51eCB2ZXJzaW9uLCAzLnhdKGh0dHBzOi8vcWdpcy5vcmcvZW4vc2l0ZS9mb3J1c2Vycy9hbGxkb3dubG9hZHMuaHRtbCNsaW51eCkNCg0KV2hlbiBpbnN0YWxsaW5nIG9uIF9tYWNPU18gZm9yIHRoZSBmaXJzdCB0aW1lIHlvdSBtYXkgbmVlZCB0byBnbyB0byBfU3lzdGVtcyBQcmVmZXJlbmNlcyA+IFNlY3VyaXR5IGFuZCBQcml2YWN5XyBhbmQgb24gdGhlIF9HZW5lcmFsXyB0YWIgIkFsbG93IGFwcHMgZG93bmxvYWRlZCBmcm9tIiBfQXBwIFN0b3JlIGFuZCBpZGVudGlmaWVkIGRldmVsb3BlcnNfIGFuZCBjbGljayBfT3BlbiBBbnl3YXlfLiBQbGVhc2UgY29udGFjdCB5b3VyIGluc3RydWN0b3IgaWYgeW91IGhhdmUgYW55IGlzc3VlcyBkb3dubG9hZGluZyBvciBpbnN0YWxsaW5nIHRoZSBzb2Z0d2FyZS4NCg0KPC9kZXRhaWxzPg0KPGhyPjwvaHI+DQoNCjxkZXRhaWxzPjxzdW1tYXJ5PjxiaWc+VmlldyBpbmZvcm1hdGlvbiBmb3IgPGI+IFtSXXtzdHlsZT0iY29sb3I6ICM2NDk1RUQifSA8L2I+PC9zcGFuPjwvYmlnPjwvc3VtbWFyeT4NCllvdSB3aWxsIGJlIGNvbXBsZXRpbmcgdGhlIDxiPltSXXtzdHlsZT0iY29sb3I6ICM2NDk1RUQifTwvYj4gcG9ydGlvbiBvZiBlYWNoIGV4ZXJjaXNlIHVzaW5nIHRoZSBfW0dvb2dsZSBDb2xhYm9yYXRvcnkgRXhlY3V0YWJsZSBFbnZpcm9ubWVudF0oaHR0cHM6Ly9jb2xhYi5yZXNlYXJjaC5nb29nbGUuY29tLylfLiBDb2xhYm9yYXRvcnksIG9yIF8iY29sYWIiXyBmb3Igc2hvcnQsIGlzIGJhc2VkIG9uIHRoZSBwb3B1bGFyIEp1cHl0ZXIgTm90ZWJvb2tzIGFuZCBhbGxvd3MgeW91IHRvIHdyaXRlIGFuZCBleGVjdXRlICoqUioqIG9yIF9QeXRob25fIGluIHlvdXIgYnJvd3Nlciwgd2l0aDoNCg0KLSBaZXJvIGNvbmZpZ3VyYXRpb24gcmVxdWlyZWQNCi0gRnJlZSBhY2Nlc3MgdG8gR1BVcw0KLSBFYXN5IHNoYXJpbmcNCg0KRWFjaCBfY29sYWJfIG5vdGVib29rIGlzIHNlcGFyYXRlZCBpbnRvIGNvZGUgY2VsbHMgYW5kIHRleHQgY2VsbHMuIEEgY29kZSBjZWxsIGlzIHVzZWQgdG8gd3JpdGUgYW5kIGV4ZWN1dGUgYSBzY3JpcHQgaW50ZXJhY3RpdmVseS4gRWFjaCB0ZXh0IGNlbGwgdXNlcyBzaW1wbGUgW21hcmtkb3duXShodHRwczovL3d3dy5tYXJrZG93bmd1aWRlLm9yZy8pIHN5bnRheCBmb3IgY3JlYXRpbmcgcGxhaW4gdGV4dCBpbmZvcm1hdGlvbi4gWW91IGNhbiBlYXNpbHkgc2hhcmUgdGhlIG5vdGVib29rIGxpa2Ugb3RoZXIgR29vZ2xlIERyaXZlIGJhc2VkIGRvY3VtZW50cyBieSBjbGlja2luZyB0aGUgIlNoYXJlIiBsaW5rIGluIHRoZSB1cHBlciByaWdodC1oYW5kIHBvcnRpb24gb2YgdGhlIHdpbmRvdy4NCg0KQmVmb3JlIGJlZ2lubmluZyBlYWNoIGV4ZXJjaXNlIHVzaW5nICoqUioqLCB5b3Ugd2lsbCBuZWVkIHRvIG9wZW4gdGhlIFtFeGVyY2lzZSBDb2xhYiBOb3RlYm9va10oaHR0cHM6Ly9naXRodWJ0b2NvbGFiLmNvbS9jaHJpc21nZW50cnkvR0lTLUV4ZXJjaXNlLTIvYmxvYi9tYWluL0dJUzFfRVgyLmlweW5iKSBhbmQgYWx0ZXIgdGhlIFVSTCB0byB2aWV3L2VkaXQgdGhlIGZpbGUgaW4gY29sYWIuIFRvIGRvIHRoaXMgeW91IHdpbGwgbmF2aWdhdGUgdG8gdGhlIGV4ZXJjaXNlJ3MgR2l0SHViIHBhZ2U7IGluIHRoaXMgY2FzZSBbaHR0cHM6Ly9naXRodWIuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTJdKGh0dHBzOi8vZ2l0aHViLmNvbS9jaHJpc21nZW50cnkvR0lTMS1FeGVyY2lzZS0yKS4gSW4gdGhlIGxpc3Qgb2YgZm9sZGVycyBhbmQgZmlsZXMgeW91IHdpbGwgZmluZCBhIGZpbGUgdGhhdCB3aWxsIGFsd2F5cyBiZSBpZGVudGlmaWVkIGFzIF9HSVMxX0VYXyBmb2xsb3dlZCBieSB0aGUgZXhlcmNpc2UgbnVtYmVyIGFuZCBhIF8uaXB5bmJfIGZpbGUgZXh0ZW5zaW9uLiBTbyBmb3IgdGhpcyBleGVyY2lzZSBpdCB3aWxsIGJlIFtHSVMxX0VYMi5pcHluYl0oaHR0cHM6Ly9naXRodWIuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTIvYmxvYi9tYWluL0dJUzFfRVgyLmlweW5iKQ0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9yLWdpdGh1Yi1pcHktbG9jYXRpb24ucG5nIiBhbHQ9IkZpbmRpbmcgdGhlIEdvb2dsZSBDb2xhYiBmaWxlIG9uIEdpdEh1YiIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD4NCjxicj4NCldoZW4geW91IGxvY2F0ZSB0aGUgZmlsZSwgY2xpY2sgb24gdGhlIG5hbWUgdG8gb3BlbiB0aGUgX2lweV8gbm90ZWJvb2suIEluIHRoZSByZXN1bHRpbmcgd2luZG93LCBjbGljayBvbiB0aGUgVVJMIGFuZCBpbnNlcnQgKip0b2NvbGFiKiogaW1tZWRpYXRlbHkgYWZ0ZXIgX2dpdGh1Yl8gaW4gdGhlIGFkZHJlc3MuIFNvIHRoZSBuZXcgVVJMIGZvciB0aGlzIGV4ZXJjaXNlIHNob3VsZCBub3cgcmVhZDo8YnI+IGBgYGh0dHBzOi8vZ2l0aHVidG9jb2xhYi5jb20vY2hyaXNtZ2VudHJ5L0dJUy1FeGVyY2lzZS0yL2Jsb2IvbWFpbi9HSVMxX0VYMi5pcHluYmBgYCANCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvci1naXRodWItdG9jb2xhYi5wbmciIGFsdD0iQ29udmVydGluZyBpcHkgZmlsZSB0byBjb2xhYiIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD4NCjxicj4NCkNsaWNrIGVudGVyL3JldHVybiBhbmQgdGhlIGZpbGUgc2hvdWxkIG5vdyBvcGVuIGluc2lkZSBvZiBfQ29sYWJfLiBZb3VyIHNjcmVlbiBtaWdodCBoYXZlIGEgc2xpZ2h0bHkgZGlmZmVyZW50IGFwcGVhcmFuY2UsIGJ1dCB5b3Ugc2hvdWxkIHNlZSB0aGUgRXhlcmNpc2UgMiwgR0lTIDEgaGVhZGVyIGluZGljYXRpbmcgeW91IGFyZSBpbiB0aGUgY29ycmVjdCBub3RlYm9vay4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvci1jb2xhYi5wbmciIGFsdD0iQ29udmVydGluZyBpcHkgZmlsZSB0byBjb2xhYiIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD4NCjxicj4NCkVhY2ggdGltZSB5b3Ugb3BlbiB0aGVzZSBjb2xhYiBub3RlYm9va3MsIG9yIGlmIHlvdSBoYXZlIG5vdCBpbnRlcmFjdGVkIHdpdGggdGhlIG5vdGVib29rIGZvciBhbiBleHRlbmRlZCBwZXJpb2Qgb2YgdGltZSwgeW91IHdpbGwgbmVlZCB0byBtYWtlIHN1cmUgdGhlIGVudmlyb25tZW50IGlzIGNvbm5lY3RlZCBhbmQgYWxsIG9mIHRoZSBzYW1wbGUgc2NyaXB0IGhhcyBiZWVuIHJ1bi4gVG8gZG8gdGhpcyBnbyB0byBfUnVudGltZSA+IFJ1biBhbGxfIChvciBjbGljayBDUlRMK0Y5KSBhbmQgcnVuIHRoZSBub3RlYm9vay4gVGhpcyBtYXkgdGFrZSBhIG1vbWVudCB0byBjb21wbGV0ZSBzbyBiZSBwYXRpZW50IHVudGlsIHRoZSBsYXN0IGNvZGUgY2VsbCBoYXMgYmVlbiBleGVjdXRlZC4gWW91IHNob3VsZCBzZWUgYSBncmVlbiBjaGVjayBtYXJrIHdpdGggYW4gYWxsb2NhdGlvbiBvZiBSQU0gYW5kIERpc2sgYXMgc2hvd24gYnkgaG9yaXpvbnRhbCBiYXJzIHdoaWNoIHdpbGwgaW5kaWNhdGUgeW91IGFyZSBjb25uZWN0ZWQuIEluIGVhY2ggc2VjdGlvbiBvZiBjb2RlIHRoZXJlIGlzIGEgKipSdW4gY2VsbCoqICZuYnNwOzxpbWcgc3JjPSAiSW1hZ2VzL3ItY29sYWItcnVuLWNvZGUucG5nIiBhbHQ9IlJ1biBjZWxsIGJ1dHRvbiIgd2lkdGg9IjE1IiBoZWlnaHQ9IjE1Ij4gYnV0dG9uIHRoYXQgd2lsbCBhbGxvdyB5b3UgdG8gcnVuIHRoZSBpbmRpdmlkdWFsIGNvZGUgY2VsbHMuIFRoaXMgYnV0dG9uIHdpbGwgaGF2ZSBhIHJvdGF0aW5nIGxvYWRpbmcgc3ltYm9sIDxpbWcgc3JjPSAiSW1hZ2VzL3ItY29sYWItbG9hZGluZy5wbmciIGFsdD0iUnVuIGNlbGwgYnV0dG9uIiB3aWR0aD0iMTUiIGhlaWdodD0iMTUiPiB3aGlsZSB0aGUgY29kZSBjZWxsIGlzIGJlaW5nIGV4ZWN1dGVkLiBPbmNlIGl0IGlzIGNvbXBsZXRlIHRoZSBib3ggd2lsbCByZXR1cm4gdG8gdGhlIHJ1biBzdGF0ZSBhbmQgdGhlcmUgbWF5IGJlIGFuIG91dHB1dCB2aXNpYmxlIGRlcGVuZGluZyBvbiB0aGUgc2NyaXB0LiBZb3UgY2FuIGFkZCB5b3VyIG93biB0ZXh0IG9yIGNvZGUgY2VsbHMgdG8gYSBub3RlYm9vayBzaW1wbHkgYnkgbW92aW5nIHlvdXIgY3Vyc29yIHNsb3dseSBvdmVyIHRoZSBub3RlYm9vayB0byByZXZlYWwgdGhlIGNvZGUvdGV4dCBvcHRpb24gYmFyIG9yIGJ5IGdvaW5nIHRvIF9JbnNlcnQgPiBDb2RlIGNlbGwvVGV4dCBjZWxsXy4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvci1jb2xhYi1jb2RlLXRleHQucG5nIiBhbHQ9IkFkZGluZyBUZXh0IG9yIENvZGUgQmxvY2tzIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9wPg0KPGJyPg0KQnkgY2xpY2tpbmcgd2l0aGluIGVhY2ggY29kZSBvciB0ZXh0IGNlbGwgeW91IGNhbiBlZGl0IHRoZSBjb250YWlucyBhbmQgYWRqdXN0IHRoZSBwcm9wZXJ0aWVzIHVzaW5nIHRoZSB2YXJpb3VzIHByZXNldCBvcHRpb24gY29udHJvbHMuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL3ItY29sYWItYmxvY2stc2V0dGluZ3MucG5nIiBhbHQ9IkVkaXQgYmxvY2sgcHJvcGVydGllcyIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD4NCjxicj4NCllvdSBzaG91bGQgcHJhY3RpY2UgYWRkaW5nIGFuZCByZW1vdmluZyBjZWxscywgZWRpdGluZyB0aGVpciBjb250ZW50LCBhbmQgcmVhcnJhbmdpbmcgdGhlIG9yZGVyIG9mIHRoZSBjZWxscy4gVGhpcyB3aWxsIGhlbHAgZmFtaWxpYXJpemUgeW91IHdpdGggbm90ZWJvb2sgdG9vbHMgYW5kIGFsbG93IHlvdSB0byBtYW5pcHVsYXRlIG5vdGVib29rcyBpbiB0aGVzZSBleGVyY2lzZXMgYW5kIGNyZWF0ZSB5b3VyIG93biBub3RlYm9va3MgaW4gdGhlIGZ1dHVyZS4NCg0KRm9yIGVhY2ggbmV3IGV4ZXJjaXNlIHRoZXJlIHdpbGwgYmUgYSBjb2xhYiBub3RlYm9vayBhdmFpbGFibGUuIFdpdGhpbiB0aGUgbm90ZWJvb2sgd2lsbCBiZSBzYW1wbGUgY29kZSBmb3IgeW91IHRvIHJ1biwgY29kZSBjZWxscyBmb3IgeW91IHRvIGNvbXBsZXRlIGFzIHBhcnQgb2YgdGhlIGV4ZXJjaXNlIGFuZCBxdWVzdGlvbnMgdG8gYmUgYW5zd2VyZWQgd2l0aGluIGxhYmVsZWQgdGV4dCBjZWxscy4gRGV0YWlsZWQgZGlyZWN0aW9ucyB3aWxsIGJlIGF2YWlsYWJsZSBvbiB0aGUgaW5kaXZpZHVhbCBleGVyY2lzZSB3ZWJwYWdlLiBFYWNoIGNvbXBsZXRlZCBleGVyY2lzZSB3aWxsIGhhdmUgY29tcGxldGVkIGNvZGUgYW5kIHF1ZXN0aW9uIHNlY3Rpb25zIGFuZCB0aGUgbm90ZWJvb2sgbGluayBzaGFyZWQgZm9yIGEgZ3JhZGUuDQoNCjwvZGV0YWlscz4NCg0KIyBUaGUgSW50cm9kdWN0aW9uDQoNClRoZSBUZW5uZXNzZWUgVmFsbGV5IEF1dGhvcml0eSAoVFZBKSBhbmQgVGVubmVzc2VlIERlcGFydG1lbnQgb2YgRW52aXJvbm1lbnQgYW5kIENvbnNlcnZhdGlvbiAoVERFQykgYXJlIGNvbnNpZGVyaW5nIGEgcGFydG5lcnNoaXAgdG8gaW5jcmVhc2UgdGhlIG51bWJlciBvZiBlbGVjdHJpYyB2ZWhpY2xlIGNoYXJnaW5nIHN0YXRpb25zIGFjcm9zcyB0aGUgc3RhdGUuIFdpdGggZGVzdGluYXRpb25zIHN1Y2ggYXMgTmFzaHZpbGxlLCBNZW1waGlzLCBHYXRsaW5idXJnIGFuZCB0aGUgR3JlYXQgU21va3kgTW91bnRhaW5zLCBCcmlzdG9sIE1vdG9yIFNwZWVkd2F5LCBTaWduYWwgTW91bnRhaW4gYW5kIHRoZSBUZW5uZXNzZWUgQXF1YXJpdW0sIHRvdXJpc20gaXMgYSBtYWpvciBwYXJ0IG9mIHRoZSBzdGF0ZSdzIGVjb25vbXkuIFNvIGFjY29tbW9kYXRpbmcgcmVzaWRlbnRzIGFuZCB2aXNpdG9ycyB3aXRoIGVsZWN0cmljIHZlaGljbGVzIGFzIHdlbGwgYXMgY3JlYXRpbmcgYSBuZXR3b3JrIGZvciB0aG9zZSB0cmF2ZWxpbmcgdGhlIHN0YXRlcyBtYWpvciBpbnRlcnN0YXRlcyAoSS02NSwgSS00MCwgSS0yNCwgSS03NSwgZXRjLikgaXMgb2YgdXRtb3N0IGltcG9ydGFuY2UuIA0KDQpUREVDIHNheXMgdGhpcyBuZXR3b3JrIG9mIGNoYXJnaW5nIHN0YXRpb25zIHdpbGwgYWxzbyBwcm9tb3RlIGVsZWN0cmljIHZlaGljbGUgZ3Jvd3RoIGJ5IGdpdmluZyBkcml2ZXJzIGNvbmZpZGVuY2UgdGhleSB3aWxsIGhhdmUgZWFzeSBhY2Nlc3MgdG8gcmVmdWVsaW5nIHdoaWxlIGF3YXkgZnJvbSBob21lLCBlbGltaW5hdGluZyBzby1jYWxsZWQg4oCccmFuZ2UgYW54aWV0eeKAnSB0aGF0IGtlZXBzIG1hbnkgY29uc3VtZXJzIGZyb20gY29uc2lkZXJpbmcgZWxlY3RyaWMgdmVoaWNsZXMgYXMgdmlhYmxlIHRyYW5zcG9ydGF0aW9uLiBUVkEgc2F5cyBlbGVjdHJpYyB2ZWhpY2xlIGFkb3B0aW9uIHdpbGwgc3B1ciBqb2JzIGFuZCBlY29ub21pYyBpbnZlc3RtZW50IGluIHRoZSByZWdpb24sIGtlZXAgcmVmdWVsaW5nIGRvbGxhcnMgaW4gdGhlIGxvY2FsIGVjb25vbXksIHJlZHVjZSB0aGUgcmVnaW9ucyBsYXJnZXN0IHNvdXJjZSBvZiBjYXJib24gZW1pc3Npb25zLCBhbmQgc2F2ZSBkcml2ZXJzIGFuZCBmbGVldHMgbW9uZXkuDQoNClNvIFRWQSBhbmQgVERFQyBoYXZlIGFza2VkIHlvdSB0byBkZXZlbG9wIGEgbWFwIHNob3dpbmcgdGhlIG51bWJlciBvZiBwdWJsaWMgZWxlY3RyaWMgdmVoaWNsZSBjaGFyZ2luZyBzdGF0aW9ucyBpbiB0aGUgY29udGluZW50YWwgVW5pdGVkIFN0YXRlcy4gVGhpcyB3aWxsIGhlbHAgdGhlbSB1bmRlcnN0YW5kIHdoYXQgdGhlIG5hdGlvbnMgY3VycmVudCBpbmZyYXN0cnVjdHVyZSBsb29rcyBsaWtlIGFuZCBob3cgVGVubmVzc2VlIGN1cnJlbnRseSBjb21wYXJlcyB0byBuZWlnaGJvcmluZyBzdGF0ZXMuIEl0IHdpbGwgYWxzbyBoZWxwIFRWQSBhbmQgVERFQyBkZXRlcm1pbmUgYXBwcm94aW1hdGVseSBob3cgbWFueSBhZGRpdGlvbmFsIHN0YXRpb25zIHRoZXkgc2hvdWxkIGFkZC4gDQoNCkluIHRoaXMgZXhlcmNpc2UgeW91IHdpbGw6DQoNCi0gICBOYXZpZ2F0ZSBzb2Z0d2FyZSB1c2VkIGZvciBnZW9zcGF0aWFsIGFuYWx5c2lzDQotICAgRXhhbWluZSBhdHRyaWJ1dGVzIG9mIHZhcmlvdXMgZGF0YXNldHMNCi0gICBMZWFybiBob3cgdG8gZ3JhcGhpY2FsbHkgZGlzcGxheSBzcGF0aWFsIGRhdGENCi0gICBDcmVhdGUgYSBjYXJ0b2dyYXBoaWNhbGx5IHNvdW5kIHByb2R1Y3QNCg0KU29mdHdhcmUgc3BlY2lmaWMgZGlyZWN0aW9ucyBjYW4gYmUgZm91bmQgZm9yIGVhY2ggc3RlcCBiZWxvdy4gUGxlYXNlIHN1Ym1pdCB0aGUgYW5zd2VyIHRvIHRoZSBxdWVzdGlvbnMgYW5kIHlvdXIgZmluYWwgbWFwIGJ5IHRoZSBkdWUgZGF0ZS4NCg0KIyMgU3RlcCBPbmU6IFRoZSBEYXRhDQoNCl9JbnNlcnQgVGV4dCBIZXJlXw0KDQo8ZGV0YWlscz4NCjxzdW1tYXJ5PjxiaWc+VmlldyBEaXJlY3Rpb25zIGluIDxiPiBbQXJjR0lTIFByb117c3R5bGU9ImNvbG9yOiNmZjQ1MDAifSA8L2I+PC9iaWc+PC9zdW1tYXJ5Pg0KDQpfSW5zZXJ0IFRleHQgSGVyZV8NCg0KUXVlc3Rpb24gTm8uIDENCjxibG9ja3F1b3RlPg0KX0luc2VydCBUZXh0IEhlcmVfDQo8L2Jsb2NrcXVvdGU+DQoNCjwvZGV0YWlscz4NCjxocj48L2hyPg0KDQo8ZGV0YWlscz4NCjxzdW1tYXJ5PjxiaWc+VmlldyBEaXJlY3Rpb25zIGluIDxiPiBbUUdJU117c3R5bGU9ImNvbG9yOiMwMDY0MDAifSA8L2I+PC9iaWc+PC9zdW1tYXJ5Pg0KDQpUaGUgcHVycG9zZSBvZiB0aGlzIGV4ZXJjaXNlIGlzIHRvIGhlbHAgZmFtaWxpYXJpemUgeW91IHdpdGggdGhlIFtRR0lTXXtzdHlsZT0iY29sb3I6IzAwNjQwMCJ9IHByb2dyYW0uIFdpdGggdGhpcyBzb2Z0d2FyZSwgeW91IHdpbGwgaGF2ZSB0aGUgYWJpbGl0eSB0byB2aWV3LCBjcmVhdGUsIGFuZCBlZGl0IGdlb2dyYXBoaWMgZGF0YSwgcXVlcnkgc3BhdGlhbCBkYXRhLCBleGFtaW5lIHNwYXRpYWwgcmVsYXRpb25zaGlwcywgYW5kIGNyZWF0ZSBwdWJsaXNoYWJsZSBtYXBzLiBJbiB0aGVzZSBkaXJlY3Rpb25zIEkgd2lsbCBwb3N0IGltYWdlcyBmcm9tIGJvdGggUEMgKG9uIHRoZSBsZWZ0KSBhbmQgbWFjT1MgKG9uIHRoZSByaWdodCkgZm9yIGVhY2ggc3RlcC4gV2hpbGUgeW91ciBzZXQtdXAgbWF5IGRpZmZlciBzbGlnaHRseSwgdGhlIGNvbmZpZ3VyYXRpb25zIGFuZCBsYXlvdXQgb2YgdGhlIHRvb2xzIHNob3VsZCBiZSBzaW1pbGFyLg0KDQpXaGVuIHlvdSBiZWdpbiBhIG5ldyBleGVyY2lzZSBpdCB3b3VsZCBiZSBiZW5lZmljaWFsIHRvIGNyZWF0ZSBhIG5ldyBmb2xkZXIgc3BlY2lmaWNhbGx5IGZvciB0aGUgZGF0YSBhbmQgcHJvamVjdCBmaWxlcyBhc3NvY2lhdGVkIHdpdGggdGhlIGxhYi4gVGhpcyB3aWxsIGhlbHAgeW91IHRvIG9yZ2FuaXplIHlvdXIgZGF0YSBhbmQgYmUgYWJsZSB0byBxdWlja2x5IHJlZmVyIGJhY2sgdG8gaXQgaW4gbGF0ZXIgZXhlcmNpc2VzLiBGb3IgdGhpcyBleGVyY2lzZSB5b3Ugd2lsbCBuZWVkIHRvIGRvd25sb2FkIHRoZSBfRWxlY3RyaWMgVmVoaWNsZSBDaGFyZ2luZyBTdGF0aW9uXyBkYXRhIGZyb20gdGhlIFtHaXRIdWIgUmVwb3NpdG9yeV0oaHR0cHM6Ly9naXRodWIuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTIpe3N0eWxlPSJjb2xvcjojMDAwMDAwIn0gYnkgY2xpY2tpbmcgb24gdGhlIGRvd25sb2FkIGJ1dHRvbiBhdCA8Yj5bdGhpcyBsaW5rXShodHRwczovL2dpdGh1Yi5jb20vY2hyaXNtZ2VudHJ5L0dJUzEtRXhlcmNpc2UtMi9ibG9iL21haW4vRGF0YS9TaGFwZWZpbGVzL2V2X2RhdGEuemlwKXtzdHlsZT0iY29sb3I6IzAwNjQwMCJ9PC9iPiBhbmQgc2F2aW5nIGl0IGluIHlvdXIgZXhlcmNpc2UgZm9sZGVyLiBPbmNlIHRoZSBkb3dubG9hZCBpcyBjb21wbGV0ZSB5b3Ugd2lsbCBuZWVkIHRvIHVuemlwIHRoZSBmaWxlIGJ5IHVzaW5nIF9Db250cm9sK2NsaWNrXyBvbiBtYWNPUyBvciBfcmlnaHQtY2xpY2sgPiBleHRyYWN0XyBhbGwgb24gUEMuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL2dpdGh1Yi1kYXRhLWRvd25sb2FkLnBuZyIgYWx0PSJEYXRhIERvd25sb2FkIGZyb20gR2l0SHViIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9wPjxicj4NCg0KVG8gc3RhcnQgdGhlIFFHSVMgcHJvZ3JhbSBwcmVzcyB0aGUgX1N0YXJ0IE1lbnUgPiBRR0lTXyBvciBsYXVuY2ggdGhlIGFwcGxpY2F0aW9uIGZyb20gdGhlIF9NYWMgTGF1bmNocGFkXy4gSXQgbWlnaHQgYmUgYmVuZWZpY2lhbCB0byBjcmVhdGUgYSBzaG9ydGN1dCBvbiB0aGUgZGVza3RvcCBvciBhZGQgaXQgdG8geW91ciBkb2NrIGZvciBxdWlja2VyIGFjY2VzcyBpbiB0aGUgZnV0dXJlLiBBcyB0aGUgcHJvZ3JhbSBsb2FkcywgdGhlIG9wZW5pbmcgc2NyZWVuIHdpbGwgYmUgZXh0cmVtZWx5IHVzZWZ1bCB0byB5b3Ugd2hpbGUgd29ya2luZyBvbiBmdXR1cmUgcHJvamVjdHMsIGhvd2V2ZXIsIGZvciB0aGlzIGV4ZXJjaXNlIHdlIHdpbGwgc2VsZWN0ICoqTmV3IEVtcHR5IFByb2plY3QqKi4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy10ZW1wLnBuZyIgYWx0PSJRR0lTIFN0YXJ0IFNjcmVlbiIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD48YnI+DQoNClRoZSBzY3JlZW4gZGVwaWN0ZWQgYmVsb3cgaXMgc2VwYXJhdGVkIGludG8gdHdvIHNlY3Rpb25zLiBUbyB0aGUgbGVmdCB0aGVyZSBpcyB0aGUgX0Jyb3dzZXJfIGFuZCBfTGF5ZXJzXyBzZWN0aW9ucywgYW5kIG9uIHRoZSByaWdodCBpcyB0aGUgX01hcCBDYW52YXNfLiBZb3VyIHZlcnNpb24gbWF5IHZhcnkgc2xpZ2h0bHkgZnJvbSB0aGUgaW1hZ2VzLiBUaGVyZSBhcmUgYSBudW1iZXIgb2Ygd2F5cyB0byBhZGQgZGF0YSwgYnV0IGluIHRoaXMgZXhhbXBsZSB3ZSBhcmUgZ29pbmcgdG8gdXNlIHRoZSBicm93c2VyIHdpbmRvdyB0byBjb25uZWN0IHRvIG91ciBFU1JJIERhdGEgZm9sZGVyLg0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLXByb2oucG5nIiBhbHQ9IlFHSVMgU3RhcnQgU2NyZWVuIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9wPjxicj4NCg0KSW4gdGhlIF9Ccm93c2VyXyB3aW5kb3cgb24gdGhlIGxlZnQsIG5hdmlnYXRlIHRvIHRoZSBmb2xkZXIgd2hlcmUgeW91IHNhdmVkIGFuZCB1bnppcHBlZCB0aGUgZXhlcmNpc2UgZGF0YSBmb2xkZXIuIE9uY2UgeW91IGxvY2F0ZSBhIGZvbGRlciBpbiBmb2xkZXIgaW4gdGhlIGJyb3dzZXIsIHlvdSBjYW4gdXNlIGNvbnRyb2wrY2xpY2sgKG1hY09TKSBvciByaWdodC1jbGljayAoUEMpIHRvICoqQWRkIGFzIGEgZmF2b3JpdGUqKi4gVGhpcyB3aWxsIGxpbmsgaXQgdG8gdGhlIGZhdm9yaXRlcyBkcm9wLWRvd24gaW4gdGhlIGJyb3dzZXIgd2luZG93IGdpdmluZyB5b3UgcXVpY2tlciBmdXR1cmUgYWNjZXNzLiBUbyBhZGQgdGhlIGRhdGEsIHlvdSB3aWxsIG5hdmlnYXRlIHRvIHRoZSAqKmV2X2RhdGEuc2hwKiogZmlsZSBhbmQgdGhlbiBjbGljay1hbmQtZHJhZyBpdCB0byB0aGUgbWFwIGNhbnZhcy4gWW91IHdpbGwgYmUgYWJsZSB0byBhZGQgYWxsIHR5cGVzIG9mIGRhdGEgaW4gdGhpcyBzYW1lIHdheS4gSWYgdGhlcmUgaXMgYSBwb3AtdXAgd2luZG93IHRoYXQgbWVudGlvbnMgdHJhbnNmb3JtYXRpb25zIGdvIGFoZWFkIGFuZCBjbGljayBPSy4gV2hpbGUgdGhlIGxvb2sgb2YgdGhlIFVTIGluIHRoaXMgZGF0YXNldCBpcyBsZXNzIHRoYW4gaWRlYWwsIHRoZSBwdXJwb3NlIG9mIHRoaXMgZXhlcmNpc2UgaXMgdG8gZW5zdXJlIHlvdSBrbm93IGhvdyB0byBkaXNwbGF5IGRhdGEgYW5kIGJhc2ljIHRvb2xzIGZvciBuYXZpZ2F0aW5nIHRoZSBzb2Z0d2FyZS4gVHJhbnNmb3JtYXRpb25zIHdpbGwgYmUgZGlzY3Vzc2VkIGZ1cnRoZXIgaW4gYSBjb3VwbGUgd2Vla3MgYWZ0ZXIgYSBsZWN0dXJlIG9uIHByb2plY3Rpb25zIGFuZCBjb29yZGluYXRlIHN5c3RlbXMuIEZvciBub3csIGxlYXZlIGl0IHdpdGggb3B0aW9uIDEgYW5kIGNsaWNrIE9LLg0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLXRyYW5zZm9ybWF0aW9ucy5wbmciIGFsdD0iUUdJUyBTdGFydCBTY3JlZW4iIHN0eWxlPSJ3aWR0aDoxMDAlIj48L3A+PGJyPg0KDQpZb3VyIHNjcmVlbiBzaG91bGQgbm93IGxvb2sgc2ltaWxhciB0byB0aGUgc2NyZWVucyBiZWxvdyAoY29sb3JzIG1heSB2YXJ5KS4gTm90aWNlIHRoYXQgdGhlIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUgdmFsdWVzIGF0IHRoZSBib3R0b20gb2YgdGhlIHNjcmVlbiBhZGp1c3QgYXMgeW91IG1vdmUgeW91ciBjdXJzb3IuIA0KDQo8cCBhbGlnbj0iY2VudGVyIj48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLXN0YXRlcy5wbmciIGFsdD0iUUdJUyBNYXAgQ2FudmFzIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9wPjxicj4NCg0KWW91IGNhbiBub3cgYmVnaW4gdG8gZXhwbG9yZSBzb21lIG9mIHRoZSBiYXNpYyB0b29scyBmb3IgbmF2aWdhdGluZyB0aGUgX21hcCBjYW52YXNfIHN1Y2ggYXM6DQoNCjx0YWJsZSBzdHlsZT0id2lkdGg6MTAwJTttYXJnaW4tbGVmdDphdXRvO21hcmdpbi1yaWdodDphdXRvOyI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPlpvb20gaW4gYW5kIG91dCB3aXRoIHRoZSA8aT5GaXhlZCBab29tIFRvb2xzPC9pPjwvbGk+PC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1maXhlZC16b29tLnBuZyIgYWx0PSJGaXhlZCBab29tIFRvb2xzIiB3aWR0aD0iNDAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPjxpPlBhbiB0b29sPC9pPiB0byBwb3N0aW9uIHRoZSBtYXAgb24gdGhlIHNjcmVlbjwvbGk+PC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1wYW4ucG5nIiBhbHQ9IlBhbiBUb29sIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPjxpPk1hcCBzY2FsZTwvaT4gd2hlcmUgeW91IGNhbiBhZGp1c3QgdGhlIG1hcCBzY2FsZSAobGV2ZWwgb2Ygem9vbSkgbWFudWFsbHk8L2xpPjwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtbWFwLXNjYWxlLnBuZyIgYWx0PSJNYXAgU2NhbGUiIHdpZHRoPSI4MCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD48bGk+PGk+Wm9vbSBmdWxsPC9pPiBidXR0b24gd2hpY2ggd2lsbCBhZGp1c3QgdGhlIHZpZXcgdG8gYWNjb21tb2RhdGUgYWxsIGRhdGFzZXRzPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWZ1bGwtZXh0ZW50LnBuZyIgYWx0PSJab29tIEZ1bGwiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgPC90cj4NCjwvdGFibGU+DQo8YnI+DQpVc2UgdGhlc2UgdG9vbHMgdG8gem9vbSBpbiBhbmQgb3V0LCByZXBvc2l0aW9uIHRoZSBtYXAgb24gdGhlIHNjcmVlbiwgYW5kIHJldHVybiB0byB0aGUgY3VycmVudCB2aWV3IHVzaW5nIHRoZSBfem9vbSBmdWxsXyBidXR0b24uDQoNCkFub3RoZXIgdXNlZnVsIHRvb2wgaXMgdGhlICoqaWRlbnRpZnkgZmVhdHVyZXMqKiBjdXJzb3Igd2hpY2ggdXNlcyBhbiBpY29uIHdpdGggYSBsb3dlcmNhc2UgX2lfIGluIGEgW2JsdWUgY2lyY2xlXXtzdHlsZT0iY29sb3I6IzY0OTVFRCJ9IDxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtaWRlbnRpZnkucG5nIiBhbHQ9IklkZW50aWZ5IEZlYXR1cmVzIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPiAuIFRoaXMgb3B0aW9uIGV4dHJhY3RzIGluZm9ybWF0aW9uIGZvciBhIHNlbGVjdGVkIGZlYXR1cmUgZnJvbSB0aGUgYXR0cmlidXRlIHRhYmxlIG9mIHRoZSBzZWxlY3RlZCBsYXllci4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy10ZW5uZXNzZWUucG5nIiBhbHQ9IklkZW50aWZ5IEN1cnNvciIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD48YnI+DQoNCklmIHlvdSB3YW50ZWQgdG8gdmlldyB0aGUgZW50aXJlIHVuZGVybHlpbmcgZGF0YXNldCB5b3UgY291bGQgY29udHJvbC1jbGljayAobWFjT1MpIG9yIHJpZ2h0LWNsaWNrIChQQykgb24gdGhlIGFjdGl2ZSBsYXllciBhbmQgc2VsZWN0ICoqT3BlbiBhdHRyaWJ1dGUgdGFibGUqKi4gSW4gYSBmdXR1cmUgZXhlcmNpc2UgeW91IHdpbGwgbGVhcm4gaG93IHRvIHNvcnQsIHF1ZXJ5LCBhbmQgZWRpdCBpbmZvcm1hdGlvbiB3aXRoaW4gdGhlIGF0dHJpYnV0ZSB0YWJsZS4gRm9yIG5vdywgZXhhbWluZSB0aGUgbnVtZXJvdXMgdmFyaWFibGVzIGF2YWlsYWJsZSBmb3IgZWFjaCBzdGF0ZS4gV2hhdCBpcyB0aGUgY29sdW1uIG5hbWUgYW5kIHJhbmdlIG9mIHZhbHVlcyBmb3IgdGhlIGVsZWN0cmljIHZlaGljbGUgY2hhcmdpbmcgc3RhdGlvbnM/IDxicj4NCjxzbWFsbD48aT5IaW50OiBUaGlzIGluZm9ybWF0aW9uIHdpbGwgYmUgbmVlZGVkIGluIHRoZSBuZXh0IHNlY3Rpb24uPC9pPjwvc21hbGw+DQoNCjxwIGFsaWduPSJjZW50ZXIiPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtYXR0cmlidXRlcy5wbmciIGFsdD0iQXR0cmlidXRlIFRhYmxlIiBzdHlsZT0id2lkdGg6MTAwJSI+PC9wPjxicj4NCg0KPGI+PGJpZz5RdWVzdGlvbiBOby4gMTwvYmlnPjwvYj4NCjxibG9ja3F1b3RlPg0KVXNpbmcgdGhlIGlkZW50aWZ5IHRvb2wsIHdoYXQgaXMgdGhlIHBvcHVsYXRpb24gb2YgVGVubmVzc2VlIGluIDIwMTA/IFdoYXQgcGVyY2VudGFnZSBvZiB0aGUgcG9wdWxhdGlvbiBpcyBmZW1hbGU/PGJyPjxicj4NClVzaW5nIHRoZSBhdHRyaWJ1dGUgdGFibGUsIGZpbmQgdGhlIGFyZWEgKF9TUU1JXyZuYnNwOykgb2YgQ29sb3JhZG8uIEhvdyBtdWNoIGxhcmdlciBpcyBpdCB0aGFuIFd5b21pbmc/DQo8L2Jsb2NrcXVvdGU+DQoNClR5cGUgeW91ciBhbnN3ZXJzIGluIGEgd29yZCBkb2N1bWVudCBvciByZWNvcmQgdGhlIGFuc3dlcnMgb24gYSBzaGVldCBvZiBwYXBlci4gVGhleSB3aWxsIG5lZWQgdG8gYmUgc3VibWl0dGVkIGF0IHRoZSBjb25jbHVzaW9uIG9mIHRoaXMgbGFiLg0KPC9kZXRhaWxzPg0KPGhyPjwvaHI+DQoNCjxkZXRhaWxzPg0KPHN1bW1hcnk+PGJpZz5WaWV3IERpcmVjdGlvbnMgaW4gPGI+IFtSXXtzdHlsZT0iY29sb3I6IzY0OTVFRCJ9IDwvYj48L2JpZz48L3N1bW1hcnk+DQoNCkZvciBlYWNoIGV4ZXJjaXNlIGluICoqUioqIHlvdSB3aWxsIG5lZWQgdG8gbG9hZCB2YXJpb3VzIHBhY2thZ2VzIHRoYXQgYXJlIHVzZWQgdG8gY29tcGxldGUgYW5hbHlzZXMgYW5kIGdyYXBoaWNhbCBvdXRwdXQuIEdlbmVyYWxseSB0aGVzZSBwYWNrYWdlcyB3aWxsIGJlIHByZWxvYWRlZCBpbiB0aGUgY29sYWIgbm90ZWJvb2sgaG93ZXZlciBpbiBzdWJzZXF1ZW50IGxhYnMgeW91IG1heSBuZWVkIHRvIGluc3RhbGwgY2VydGFpbiBwYWNrYWdlcyB0byBjb21wbGV0ZSB0aGUgZXhlcmNpc2VzLiBUbyBpbnN0YWxsIGEgcGFja2FnZSBpbiAqKlIqKiB5b3UgdXNlIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb24gd2hlcmUgKCJ4IikgaXMgdGhlIG5hbWUgb2YgYSBzcGVjaWZpYyBwYWNrYWdlLg0KDQpgYGANCmluc3RhbGwucGFja2FnZXMoIngiKQ0KYGBgDQpPbmNlIHRoZSBwYWNrYWdlIGhhcyBiZWVuIGluc3RhbGxlZCwgaXQgd2lsbCBuZWVkIHRvIGJlIGxvYWRlZCB1c2luZyBhIHNpbWlsYXIgZnVuY3Rpb246DQoNCmBgYA0KbGlicmFyeSgieCIpDQpgYGANCkluIHRoZSBjb2xhYiBub3RlYm9vayBmb3IgdGhpcyBleGVyY2lzZSB5b3Ugd2lsbCBzZWUgd2hlcmUgdGhyZWUgcGFja2FnZXMgX3RpZHl2ZXJzZSwgbWFwcywgYW5kIGdnc25fIHdlcmUgaW5zdGFsbGVkIGFuZCBsb2FkZWQuIE5vdyB0aGF0IHlvdSBoYXZlIHRoZSBwYWNrYWdlcyByZXF1aXJlZCBmb3IgdGhlIGV4ZXJjaXNlIHlvdSB3aWxsIG5lZWQgdG8gYWRkIHRoZSBkYXRhLiBGb3IgdGhpcyBsYWIgdGhlIGRhdGEgY29uc2lzdHMgb2Ygc3RhdGUgbmFtZXMsIGFiYnJldmlhdGlvbnMsIGFuZCB0aGUgbnVtYmVyIG9mIGVsZWN0cmljIHZlaGljbGUgcmVjaGFyaW5nIHN0YXRpb25zLiBUbyBhdm9pZCB0aGUgbmVlZCB0byBkb3dubG9hZCB0aGUgZGF0YSwgeW91IHdpbGwgdGhlIGBgYHJlYWQuY3N2KClgYGAgZnVuY3Rpb24gYW5kIGEgVVJMIHRvIGltcG9ydCB0aGUgZGF0YS4gVXNpbmcgdGhlIGBgYGhlYWQoKWBgYCBmdW5jdGlvbiB3aWxsIGFsbG93IHlvdSB0byB2aWV3IHRoZSBmaXJzdCBmZXcgbGluZXMgb2YgYW55IGRhdGFzZXQuDQoNCmBgYHtyIGRhdGEsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmV2cyA8LSByZWFkLmNzdignaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTIvbWFpbi9EYXRhL2V2X3N0YXRpb25zLmNzdicpDQpoZWFkKGV2cykNCmBgYA0KDQpJbiB0aGUgc2NyaXB0IGFib3ZlIHlvdSB3aWxsIHNlZSB0aGUgdXNlIG9mICZuYnNwOyoqPC0qKi4gVGhpcyBpcyBhbiBvcGVyYXRvciB1c2VkIHRvIGNyZWF0ZSBhbiBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCBpbiBsYXRlciBzdGVwcy4gSWYgdGhlIHNjcmlwdCB3YXMgd3JpdHRlbiBhcyBgYGByZWFkLmNzdignaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2NocmlzbWdlbnRyeS9HSVMxLUV4ZXJjaXNlLTIvbWFpbi9EYXRhL2V2X3N0YXRpb25zLmNzdicpYGBgIHRoZSBkYXRhc2V0IHdvdWxkIGhhdmUgYmVlbiByZWFkIGFuZCBpbW1lZGlhdGVseSBkaXNwbGF5ZWQgb24gdGhlIHNjcmVlbi4gSG93ZXZlciwgaXQgd291bGQgbm90IGhhdmUgYmVlbiBhdmFpbGFibGUgZm9yIHN1YnNlcXVlbnQgYW5hbHlzZXMuIEluIGNvbGFiLCB5b3UgY2FuIGNyZWF0ZSB5b3VyIG93biBjb2RlIGJsb2NrIGFuZCB0ZXN0IGl0IG91dCB0byBzZWUgdGhlIHJlc3VsdHMuIFNpbmNlIHlvdSBuZWVkIHRoaXMgaW5mb3JtYXRpb24gZm9yIGxhdGVyLCBpdCBpcyBpbXBvcnRhbnQgdG8gdXNlICZuYnNwOyoqPC0qKiB0byBjcmVhdGUgYW4gb2JqZWN0IG91dCBvZiB0aGUgaW1wb3J0ZWQgZGF0YS4gSW4gdGhpcywgYW5kIGZ1dHVyZSBleGVyY2lzZXMsIHlvdSB3aWxsIHNlZSB0aGF0IG9wZXJhdG9yIHVzZWQgZnJlcXVlbnRseSB0byBjcmVhdGUgb2JqZWN0cyBmb3IgYW5hbHlzaXMuIA0KDQpJbiBvcmRlciB0byBjcmVhdGUgYSBtYXAgb2YgZWxlY3RyaWNhbCB2ZWhpY2xlIGNoYXJnaW5nIHN0YXRpb25zIHBlciBzdGF0ZSB5b3UgbmVlZCB0byBvYnRhaW4gaW5mb3JtYXRpb24gZm9yIHRoZSBzdGF0ZXMgYW5kIGNyZWF0ZSBhIG5ldyBvYmplY3QuIFRoZSBgYGB0aWR5dmVyc2VgYGAgcGFja2FnZSBpcyBhIHJldGFpbmVyIGZvciBhIG51bWJlciBvZiBpbmRpdmlkdWFsIHBhY2thZ2VzIGluY2x1ZGluZyB0aGUgX0dyYW1tYXIgb2YgR3JhcGhpY3NfIG9yIF9nZ3Bsb3QyXyBwYWNrYWdlLiBUaGlzIHBhY2thZ2Ugd2lsbCBmcmVxdWVudGx5IGJlIHVzZWQgdG8gZGlzcGxheSB5b3VyIGRhdGEsIGJ1dCBpdCBhbHNvIGNvbnRhaW5zIGdlb2dyYXBoaWMgaW5mb3JtYXRpb24gZm9yIHRoZSBVUy4gWW91IGNhbiBvYnRhaW4gdGhhdCBpbmZvcm1hdGlvbiBieSB1c2luZyB0aGUgYGBgbWFwX2RhdGFgYGAgZnVuY3Rpb24uIEluIGEgbmV3IGNvZGUgYmxvY2ssIHlvdSBjYW4gdXNlIGBgYD9tYXBfZGF0YWBgYCB0byB2aWV3IGhlbHAgaW5mb3JtYXRpb24gb24gdGhlIGZ1bmN0aW9uLiBBbHRlcm5hdGl2ZWx5IHlvdSBjYW4gdmlldyB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgYW55IHBhY2thZ2Ugb3IgZnVuY3Rpb24gYnkgc2VhcmNoaW5nIHRoZSBwYWNrYWdlIG9yIGZ1bmN0aW9uIG5hbWUgYW5kIGNyYW4gXyhDb21wcmVoZW5zaXZlIFIgQXJjaGl2ZSBOZXR3b3JrKV8uIEZvciB0aGlzIGZ1bmN0aW9uIHlvdSB3b3VsZCBzZWFyY2ggYGBgbWFwX2RhdGEgY3JhbmBgYCBhbmQgdGhlIGZpcnN0IGxpbmsgaXMgbGlrZWx5IHRvIGJlIHRoZSBbUkRvY3VtZW50YXRpb24gcGFnZV0oaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL2dncGxvdDIvdmVyc2lvbnMvMy4zLjMvdG9waWNzL21hcF9kYXRhKSBmb3IgdGhlIGZ1bmN0aW9uLiBXaXRoaW4gdGhpcyBkb2N1bWVudGF0aW9uIHlvdSB3aWxsIGZpbmQgdGhlIGFyZ3VtZW50cyBhdmFpbGFibGUgZm9yIHRoZSBmdW5jdGlvbiBhbmQgZXhhbXBsZSBzY3JpcHRzLiBTbyB0byBjcmVhdGUgYW4gb2JqZWN0IHRoYXQgY29udGFpbnMgaW5mb3JtYXRpb24gZm9yIHRoZSBjb250aW5lbnRhbCBVUyB5b3UgY2FuIHVzZToNCg0KYGBge3Igc3RhdGVzLCBlY2hvPVRSVUUsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp1cyA8LSBtYXBfZGF0YSgnc3RhdGUnKQ0KYGBgDQoNClVzaW5nIHRoZSBfR3JhbW1hciBvZiBHcmFwaGljc18gcGFja2FnZSwgYGBgZ2dwbG90MmBgYCwgeW91IGNhbiBjcmVhdGUgYSB2aXN1YWxpemF0aW9uIG9mIHRoaXMgZGF0YS4gSGVyZSBpcyB0aGF0IHNjcmlwdDoNCg0KYGBge3Igc3RhdGVzIG1hcCwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZ2dwbG90KHVzKSArIA0KICBnZW9tX3BvbHlnb24oYWVzKHg9bG9uZywgeT1sYXQsIGdyb3VwPWdyb3VwKSwgY29sb3IgPSAid2hpdGUiKQ0KYGBgDQpJbiB0aGlzIHNjcmlwdCB5b3UgaWRlbnRpZmllZCB0aGF0IHlvdSB3YW50ZWQgdG8gdXNlIGBgYGdncGxvdGBgYCB0byB2aXN1YWxpemUgdGhlICoqdXMqKiBvYmplY3QgeW91IGNyZWF0ZWQgaW4gdGhlIHByZXZpb3VzIHN0ZXAuIE5leHQgYGBgZ2dwbG90YGBgIG5lZWRzIHRvIGtub3cgd2hhdCBzb3J0IG9mIG9iamVjdCB0byBkcmF3LiBUaGlzIGlzIGRvbmUgYnkgdXNpbmcgdGhlIGBgYGdlb21fYGBgIGZ1bmN0aW9uIGZvbGxvd2VkIGJ5IGEgdHlwZSBvZiBnZW9tZXRyeS4gVGhleSBpbmNsdWRlIHBvaW50LCBsaW5lLCBwb2x5Z29uIGFuZCBvdGhlciBnZW9tZXRyaWVzIHN1Y2ggYXMgaGlzdG9ncmFtcywgYm94cGxvdHMsIHZpb2xpbiBwbG90cyBmb3Igc3RhdGlzdGljcywgb3IgY29udG91cnMsIHJhc3RlcnMsIGFuZCB0aWxlcyBmb3IgdGhyZWUgZGltZW5zaW9uYWwgZGF0YS4gU28gZm9yIHRoaXMgc3RlcCB5b3UgdXNlZCBgYGBnZW9tX3BvbHlnb25gYGAuIE5leHQsIGBgYGdncGxvdGBgYCBuZWVkcyB0byBrbm93IGhvdyB0aGUgZGF0YSBzaG91bGQgYmUgZGlzcGxheWVkLiBJZiB5b3UgY3JlYXRlIGEgbmV3IGNvZGUgYmxvY2sgYW5kIHR5cGUgYGBgc3RyKHVzKWBgYCB5b3UgY2FuIHNlZSB0aGUgc3RydWN0dXJlIG9mIHRoZSBkYXRhIGFuZCBhIGZldyBvZiB0aGUgdmFyaWFibGVzLiBZb3Ugd2lsbCBub3RpY2UgdGhlIGRhdGFzZXQgY29udGFpbnMgX2xvbmdfIChsb25naXR1ZGUpLCBfbGF0XyAobGF0aXR1ZGUpLCBfZ3JvdXBfLCBfb3JkZXJfLCBfcmVnaW9uXyAodGhlIHN0YXRlIG5hbWVzKSwgYW5kIF9zdWJyZWdpb25fLiBTbyBpbiBgYGBnZ3Bsb3RgYGAgeW91IHByb3ZpZGUgYSBzZXJpZXMgb2YgYWVzdGhldGljcyB1c2luZyBgYGBhZXMoKWBgYCB0byBkaXJlY3QgYGBgZ2dwbG90YGBgIG9uIGhvdyB0byBkaXNwbGF5IHRoZSBkYXRhLiBJbiB0aGlzIGNhc2UsIGBgYHggPSBsb25nLCB5ID0gbGF0YGBgLCBhbmQgeW91IG5lZWQgdG8gdGVsbCBpdCB0byBvcmdhbml6ZSB0aGUgZ3JvdXBzIGJ5IHRoZSBjYXRlZ29yeSBncm91cC4gSWYgeW91IGxlYXZlIG91dCBfZ3JvdXBfIGZvciB0aGlzIHNwZWNpZmljIHNjcmlwdCwgYGBgZ2dwbG90YGBgIHdpbGwgYmUgdW5zdXJlIHdoYXQgb3JkZXIgdG8gZHJhdyB0aGUgcG9seWdvbnMgYW5kIHlvdXIgbWFwIHdpbGwgbm90IGFwcGVhciBjb3JyZWN0bHkuIGBgYGNvbG9yID0gIndoaXRlImBgYCB0ZWxscyBgYGBnZ3Bsb3RgYGAgdG8gdXNlIHdoaXRlIGJvcmRlcnMgZm9yIHRoZSBpbmRpdmlkdWFsIHN0YXRlcy4gV2hhdCBkbyB5b3UgdGhpbmsgd291bGQgaGFwcGVuIGlmIHlvdSBjaGFuZ2UgdGhlIHdvcmQgKipfY29sb3JfKiogdG8gKipfZmlsbF8qKiZuYnNwOz8gSW4gdGhlIHJlc3VsdGluZyBpbWFnZSwgYGBgZ2dwbG90YGBgIHVzZWQgdGhlIGluZm9ybWF0aW9uIGZyb20geW91ciBhZXN0aGV0aWNzIHRvIGRyYXcgdGhlIHBvbHlnb25zIGFuZCBhdXRvbWF0ZSBsYWJlbHMgZm9yIHRoZSB4IGFuZCB5IGF4ZXMuIEluIGEgbGF0ZXIgc3RlcCB5b3Ugd2lsbCBsZWFybiBob3cgdG8gY3VzdG9taXplIHRob3NlIGxhYmVscy4NCg0KSXQgbWF5IHNlZW0gYXMgaWYgdGhpcyBpcyBhIGRpZmZpY3VsdCB3YXkgdG8gdmlldyB0aGUgZGF0YS4gSW4gb3RoZXIgc29mdHdhcmUgd2l0aCBhIGdyYXBoaWNhbCB1c2VyIGludGVyZmFjZSAoR1VJKSB5b3Ugd291bGQgbW9zdCBsaWtlbHkgY2xpY2sgb3BlbiwgbmF2aWdhdGUgdG8gdGhlIGZvbGRlciBjb250YWluaW5nIHRoZSBkYXRhLCBkb3VibGUtY2xpY2sgb24gdGhhdCBkYXRhc2V0LCBhbmQgdGhlbiBpdCB3b3VsZCBhcHBlYXIgb24geW91ciBzY3JlZW4uIEVzc2VudGlhbGx5LCBldmVyeSB0aW1lIHlvdSBjbGljayAib3BlbiIgb24gYSBHVUkgaW50ZXJmYWNlLCBpdCBpcyBleGVjdXRpbmcgYSBzcGVjaWZpYyBzZXQgb2Ygc2NyaXB0cyB0byAxLikgb3BlbiB0aGUgbmF2aWdhdGlvbiB3aW5kb3csIDIuKSBhbGxvdyB0aGUgc2VsZWN0ZWQgZmlsZSB0byBiZSBpbXBvcnRlZCwgYW5kIDMuKSB0aGVuIGRpc3BsYXkgdGhlIGluZm9ybWF0aW9uIG9uIHlvdXIgc2NyZWVuLiBXaGF0IHlvdSBkaWQgYWJvdmUgaW4gdGhyZWUgbGluZXMgb2YgY29kZSB3YXMgdG8gdGVsbCBgYGBnZ3Bsb3RgYGAgdG8gMS4pIGNyZWF0ZSBhbiBvYmplY3QgY2FsbGVkIF91c18gYW5kIDIuKSBkaXNwbGF5IGl0IG9uIHRoZSBzY3JlZW4gd2l0aCBzb21lIHNwZWNpZmljIHBhcmFtZXRlcnMuIFRoZSBiZW5lZml0IG9mIGNvbXBsZXRpbmcgdGhpcyBpbiAqKlIqKiB2ZXJzdXMgc29tZXRoaW5nIHdpdGggYSBHVUkgaW50ZXJmYWNlIGlzLCBpZiB5b3UgaGFkIHRocmVlIG1vcmUgc2ltaWxhciBkYXRhc2V0cyB0byB2aWV3LCB5b3Ugd291bGQgc2ltcGx5IGNoYW5nZSBfVVNfIHRvIGFub3RoZXIgb2JqZWN0IGFuZCByZS1ydW4gdGhlIHNjcmlwdC4gVG8gcmVwZWF0IHRoZSBwcm9jZXNzIGluIGEgR1VJIGludGVyZmFjZSB5b3Ugd291bGQgbmVlZCB0byByZXBlYXQgYWxsIG9mIHRoZSBzdGVwcyBmcm9tIHRoZSBiZWdpbm5pbmcuIFRoaXMgbWlnaHQgbm90IHNlZW0gbGlrZSBtdWNoIGZvciB0aHJlZSBzdGVwcywgYnV0IHdoYXQgaWYgeW91ciB2aXN1YWxpemF0aW9uIGhhZCB0d2VudHkgc3RlcHMsIGFzIG1hbnkgZG8/IEluICoqUioqIHlvdSB3b3VsZCBzdGlsbCBzaW1wbHkgY2hhbmdlIHRoZSBkYXRhc2V0IGFuZCBydW4gdGhlIHNhbWUgc2NyaXB0LCBidXQgaW4gb3RoZXIgcHJvZ3JhbXMgeW91IHdvdWxkIG5lZWQgdG8gcmVwZWF0IHRoZSBzYW1lIHR3ZW50eSBzdGVwcyBmb3IgZWFjaCBkYXRhc2V0LiBBZGRpdGlvbmFsbHksIGlmIGEgY29sbGVhZ3VlIHdhbnRlZCB0byBkaXNwbGF5IHNvbWUgZGF0YSBpbiB0aGUgc2FtZSB3YXksIHlvdSBjYW4gZWl0aGVyIGNvcHkgYW5kIHBhc3RlIHRoZSBjb2RlIG9yIHR5cGUgb3V0IGVhY2ggb2YgdGhlIHR3ZW50eSBzdGVwcyB3aXRoIGRpcmVjdGlvbnMuIFdoaWNoIG9mIHRoZXNlIHNlZW1zIHRvIGJlIG1vcmUgY29uc2lzdGVudGx5IHJlcGVhdGFibGU/IE9uY2UgeW91IGJlZ2luIHRvIHVuZGVyc3RhbmQgdGhlIHN5bnRheCAob3JkZXIgb3IgYXJyYW5nZW1lbnQgb2Ygd29yZHMgYW5kIHBocmFzZXMgdG8gZm9ybSBwcm9wZXIgc2NyaXB0cykgeW91IHdpbGwgYmUgbW9yZSBlYXNpbHkgYWJsZSB0byBpbnRlcnByZXQgc2FtcGxlIHNjcmlwdHMgYW5kIGZpeCBlcnJvcnMgaW4geW91ciBvd24gY29kZS4NCg0KPGJpZz48Yj5RdWVzdGlvbiBOby4gMTwvYj48L2JpZz4NCjxibG9ja3F1b3RlPg0KWW91IHVzZWQgYGBgZ2dwbG90KHVzKSArIGdlb21fcG9seWdvbihhZXMoeD1sb25nLCB5PWxhdCwgZ3JvdXA9Z3JvdXApLCBjb2xvciA9ICJ3aGl0ZSIpYGBgIHRvIGNyZWF0ZSB0aGUgdmlzdWFsaXphdGlvbiBpbiB0aGlzIHN0ZXAuIFdoYXQgc2NyaXB0IHdvdWxkIHlvdSB1c2UgdG8gbWFrZSB0aGUgc2FtZSBtYXAgYnV0IHdpdGggX2JsYWNrXyBib3JkZXJzIGFuZCBfYmx1ZV8gc3RhdGVzPyBBZGQgYSBjb2RlIGNlbGwgYmVsb3cgdGhpcyBvbmUsIHR5cGUgdGhlIHNjcmlwdCwgYW5kIHJ1biBpdCB0byB2aWV3IHRoZSBvdXRwdXQuDQo8c21hbGw+SGludDogY29sb3IgPSAiLi4uLi4iLCBmaWxsID0gIi4uLi4uIjwvc21hbGw+DQo8L2Jsb2NrcXVvdGU+DQoNCjwvZGV0YWlscz4NCg0KIyMgU3RlcCBUd286IFRoZSBBbmFseXNpcw0KDQpJbiB0aGlzIHN0ZXAgeW91IHdpbGwgb3JnYW5pemUgYW5kIGRpc3BsYXkgdGhlIGRhdGEgaW4gb3JkZXIgdG8gcHJlcGFyZSBpdCBmb3IgdGhlIGZpbmFsIHZpc3VhbGl6YXRpb24uIA0KDQo8ZGV0YWlscz4NCjxzdW1tYXJ5PjxiaWc+VmlldyBEaXJlY3Rpb25zIGluIDxiPiBbQXJjR0lTIFByb117c3R5bGU9ImNvbG9yOiNmZjQ1MDAifSA8L2I+PC9iaWc+PC9zdW1tYXJ5Pg0KDQpfSW5zZXJ0IFRleHQgSGVyZV8NCg0KPC9kZXRhaWxzPg0KPGhyPjwvaHI+DQoNCjxkZXRhaWxzPg0KPHN1bW1hcnk+PGJpZz5WaWV3IERpcmVjdGlvbnMgaW4gPGI+IFtRR0lTXXtzdHlsZT0iY29sb3I6IzAwNjQwMCJ9IDwvYj48L2JpZz48L3N1bW1hcnk+DQoNCk5vdyB0aGF0IHlvdSBoYXZlIHRoZSBkYXRhIGRpc3BsYXllZCBvbiB0aGUgc2NyZWVuIGFuZCB1bmRlcnN0YW5kIGhvdyB0byBhY2Nlc3MgdGhlIHVuZGVybHlpbmcgZGF0YSwgeW91IG5lZWQgdG8gY3VzdG9taXplIHRoZSB2aWV3IHNvIHlvdSBjYW4gc2VlIHRoZSBzcGF0aWFsIGRpc3RyaWJ1dGlvbiBvZiBlbGVjdHJpYyB2ZWhpY2xlIGNoYXJnaW5nIHN0YXRpb25zIGluIHRoZSBVUy4gVG8gYmVnaW4geW91IHdpbGwgbmVlZCB0byBjb250cm9sLWNsaWNrIChtYWNPUykgb3IgcmlnaHQtY2xpY2sgKFBDKSBvbiB0aGUgKipldl9kYXRhKiogaW4geW91ciBfbGF5ZXJzXyBhbmQgY2xpY2sgb24gcHJvcGVydGllcy4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1yY3Byb3BlcnRpZXMucG5nIiBhbHQ9IlJpZ2h0IENsaWNrIFByb3BlcnRpZXMiIHN0eWxlPSJ3aWR0aDo2MCUiPjwvcD48YnI+DQoNCkluIHRoZSByZXN1bHRpbmcgd2luZG93IHlvdSB3aWxsIG5lZWQgdG8gZ28gdG8gdGhlICoqU3ltYm9sb2d5KiogdGFiICg8aT4xLjwvaT4pIGluIHRoZSBsZWZ0LWhhbmQgbWVudS4gSW4gdGhpcyB3aW5kb3cgeW91IGNhbiBjaGFuZ2UgdGhlIGZpbGwgb2YgdGhlIHBvbHlnb25zIGFuZCBjaGFuZ2UgdGhlaXIgb3BhY2l0eSAob3IgbGV2ZWwgb2YgdHJhbnNwYXJlbmN5KS4gWW91IGNhbiBhbHNvIGFkanVzdCB0aGUgc3ltYm9sb2d5IG9mIHlvdXIgZGF0YXNldC4gVGhvc2Ugb3B0aW9ucyBhcmUgYXZhaWxhYmxlIGluIGEgc2VsZWN0aW9uIGJhciBhdCB0aGUgdG9wIG9mIHRoZSB3aW5kb3cuIEZvciB0aGlzIGRhdGFzZXQgdGhleSBhcmU6DQoNCjx0YWJsZSBzdHlsZT0id2lkdGg6NTAlO21hcmdpbi1sZWZ0OmF1dG87bWFyZ2luLXJpZ2h0OmF1dG87Ij4NCiAgPHRyPg0KICAgIDx0ZD48bGk+Tm8gU3ltYm9sPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLW5vLXN5bWJvbHMucG5nIiBhbHQ9Ik5vIFN5bWJvbHMiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD48bGk+U2luZ2xlIFN5bWJvbDwvbGk+PC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1zaW5nbGUtc3ltYm9sLnBuZyIgYWx0PSJTaW5nbGUgU3ltYm9sIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPkNhdGVnb3JpemVkPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWNhdGVnb3JpemVkLXN5bWJvbC5wbmciIGFsdD0iQ2F0ZWdvcml6ZWQgU3ltYm9scyIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICA8L3RyPg0KICA8dHI+DQogICAgPHRkPjxsaT5HcmFkdWF0ZWQ8L2xpPjwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtZ3JhZHVhdGVkLXN5bWJvbC5wbmciIGFsdD0iR3JhZHVhdGVkIFN5bWJvbHMiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD48bGk+UnVsZS1iYXNlZDwvbGk+PC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1ydWxlLWJhc2VkLXN5bWJvbC5wbmciIGFsdD0iUnVsZSBCYXNlZCBTeW1ib2xzIiB3aWR0aD0iMjAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPkludmVydGVkIFBvbHlnb25zPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWludnBvbHktc3ltYm9sLnBuZyIgYWx0PSJJbnZlcnRlZCBQb2x5Z29uIFN5bWJvbHMiIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD48bGk+Mi41IEQ8L2xpPjwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtMjVELXN5bWJvbC5wbmciIGFsdD0iMi41IEQgU3ltYm9scyIgd2lkdGg9IjIwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICA8L3RyPg0KPC90YWJsZT4NCjxicj4NCkZvciB0aGlzIHNwZWNpZmljIGRhdGEgeW91IHdpbGwgY2hvb3NlIF9HcmFkdWF0ZWRfICg8aT4yLjwvaT4pIHNpbmNlIHRoZSBkYXRhIG5lZWRzIHRvIGJlIGRpc3BsYXllZCBieSBhIHJhbmdlIG9mIG51bWVyaWMgdmFsdWVzLiBOZXh0IHlvdSB3aWxsIHNlbGVjdCB0aGUgKipldl9zdGF0aW9uKiogdmFyaWFibGUgKDxpPjMuPC9pPikgaW4gdGhlIGRhdGFzZXQuIEluIHRoZSBkcm9wLWRvd24gZm9yIHRoZSBfQ29sb3IgcmFtcF8gb3B0aW9uIHlvdSBoYXZlIGEgbnVtYmVyIG9mIGNvbG9yIG9wdGlvbnMgdG8gY2hvb3NlLiBGb3IgdGhpcyBleGFtcGxlIHNlbGVjdCAqKlZpcmlkaXMqKiAoPGk+NC48L2k+KS4gIERvIHlvdSByZWNhbGwgd2hhdCB0aGUgcmFuZ2Ugb2YgdmFsdWVzIGZvciB0aGUgKipldl9zdGF0aW9uKiogZGF0YT8gQmVjYXVzZSB0aGUgbGFyZ2VzdCB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gMzAsMDAwIGFuZCB0aGUgc21hbGxlc3QgdmFsdWUgaXMgYXJvdW5kIDEwMCwgeW91IHdpbGwgbmVlZCB0byBzZXQgdGhlIF9Nb2RlXyB0byBhIF9sb2dhcml0aG1pYyBzY2FsZV8gKDxpPjUuPC9pPikgdG8gcHJvcGVybHkgZGlzcGxheSB0aGUgZGF0YSB3aGlsZSBhdm9pZGluZyBhIGJpYXMgb2YgdGhlIGxhcmdlciB2YWx1ZXMuIENoYW5nZSB0aGUgX0NsYXNzZXNfIHRvIDYgKDxpPjYuPC9pPikgYW5kIGNsaWNrICoqT0sqKiAoPGk+Ny48L2k+KS4NCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1zeW1ib2xvZ3ktb3B0aW9ucy5wbmciIGFsdD0iU3ltYm9sb2d5IFByb3BlcnRpZXMiIHN0eWxlPSJ3aWR0aDoxMDAlIj48L3A+DQo8cCBhbGlnbj0iY2VudGVyIj48c21hbGw+PGI+QmVjYXVzZSB0aGUgbWFjT1MgYW5kIFBDIHZlcnNpb25zIGFyZSBpZGVudGljYWwgb25seSBvbmUgaW1hZ2UgaXMgc2hvd24uPC9iPjwvc21hbGw+PC9wPjxicj4NCg0KWW91ciBzY3JlZW4gc2hvdWxkIG5vdyBsb29rIHNpbWlsYXIgdG8gdGhpczoNCg0KPHAgYWxpZ249ImNlbnRlciI+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy12aXJpZGlzLnBuZyIgYWx0PSJHcmFkdWF0ZWQgRGF0YSIgc3R5bGU9IndpZHRoOjEwMCUiPjwvcD4NCg0KQXQgdGhpcyBwb2ludCB5b3Ugc2hvdWxkIHNhdmUgeW91ciB3b3JrLiBXaGV0aGVyIHVzaW5nIG1hY09TIG9yIFBDLCBvbiB0aGUgbWVudSBiYXIgZ28gdG8gX1Byb2plY3QgPiBTYXZlIEFzLi4uXyBhbmQgc2F2ZSB5b3VyIHByb2plY3QgaW4gdGhlIGZvbGRlciB5b3UgY3JlYXRlIGZvciB0aGlzIGV4ZXJjaXNlLg0KDQo8YmlnPjxiPlF1ZXN0aW9uIE5vLiAyPC9iPjwvYmlnPjxicj4NCkluIHRoaXMgc3RlcCB5b3UgdXNlZCBhIF9HcmFkdWF0ZWRfIHN5bWJvbG9neSB0byB2aXN1YWxpemUgdGhlIGRhdGEgYW5kIG9yZ2FuaXplZCB0aGUgdmFsdWVzIF9sb2dhcml0aG1pY2FsbHlfLiBUaGVyZSB3ZXJlIHNldmVyYWwgb3RoZXIgb3B0aW9ucyB3aXRoaW4gX21vZGVfIG1lbnUuIA0KDQo8dGFibGUgc3R5bGU9IndpZHRoOjc1JTttYXJnaW4tbGVmdDphdXRvO21hcmdpbi1yaWdodDphdXRvOyI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPkVxdWFsIENvdW50IChRdWFudGlsZSk8L2xpPjwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtZXF1YWwtY291bnQucG5nIiBhbHQ9IkVxdWFsIENvdW50IiB3aWR0aD0iMTQwIiBoZWlnaHQ9IjIwIj48L3RkPg0KICA8L3RyPg0KICA8dHI+DQogICAgPHRkPjxsaT5FcXVhbCBJbnRlcnZhbDwvbGk+PC90ZD4NCiAgICA8dGQ+PGltZyBzcmM9ICJJbWFnZXMvcWdpcy1lcXVhbC1pbnRlcnZhbC5wbmciIGFsdD0iRXF1YWwgSW50ZXJ2YWwiIHdpZHRoPSIxNDAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPkxvZ2FyaXRobWljIFNjYWxlPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLWxvZy1zY2FsZS5wbmciIGFsdD0iTG9nYXJpdGhtaWMgU2NhbGUiIHdpZHRoPSIxNDAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPk5hdHVyYWwgQnJlYWtzIChKZW5rcyk8L2xpPjwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtamVua3MucG5nIiBhbHQ9Ik5hdHVyYWwgQlJlYWtzIChKZW5rcykiIHdpZHRoPSIxNDAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQogIDx0cj4NCiAgICA8dGQ+PGxpPlByZXR0eSBCcmVha3M8L2xpPjwvdGQ+DQogICAgPHRkPjxpbWcgc3JjPSAiSW1hZ2VzL3FnaXMtcHJldHR5LWJyZWFrcy5wbmciIGFsdD0iUHJldHR5IEJyZWFrcyIgd2lkdGg9IjE0MCIgaGVpZ2h0PSIyMCI+PC90ZD4NCiAgPC90cj4NCiAgPHRyPg0KICAgIDx0ZD48bGk+U3RhbmRhcmQgRGV2aWF0aW9uPC9saT48L3RkPg0KICAgIDx0ZD48aW1nIHNyYz0gIkltYWdlcy9xZ2lzLXNkLnBuZyIgYWx0PSJTdGFuZGFyZCBEZXZpYXRpb24iIHdpZHRoPSIxNDAiIGhlaWdodD0iMjAiPjwvdGQ+DQogIDwvdHI+DQo8L3RhYmxlPg0KDQo8YmxvY2txdW90ZT4NCkFkanVzdGluZyB0aGUgX21vZGVfIHZhbHVlLCBkZXNjcmliZSBob3cgdGhlIHZpc3VhbGl6YXRpb24gY2hhbmdlcyB3aXRoIGVhY2ggb2YgdGhlc2UgZGlmZmVyZW50IG9wdGlvbnMuDQo8L2Jsb2NrcXVvdGU+DQpSZWNvcmQgeW91ciBhbnN3ZXJzIGFuZCBzdWJtaXQgYXQgdGhlIGNvbmNsdXNpb24gb2YgdGhlIGxhYi4NCjwvZGV0YWlscz4NCjxocj48L2hyPg0KDQo8ZGV0YWlscz4NCjxzdW1tYXJ5PjxiaWc+VmlldyBEaXJlY3Rpb25zIGluIDxiPiBbUl17c3R5bGU9ImNvbG9yOiM2NDk1RUQifSA8L2I+PC9iaWc+PC9zdW1tYXJ5Pg0KDQpOb3cgdGhhdCB5b3UgaGF2ZSBkYXRhc2V0cyBmb3IgZWxlY3RyaWMgdmVoaWNsZSBjaGFyZ2luZyBzdGF0aW9ucyAob2JqZWN0ID0gKipldnMqKikgYW5kIHRoZSBjb250aW5lbnRhbCBVUyAob2JqZWN0ID0gKip1cyoqKSwgeW91IG5lZWQgdG8gY29tYmluZWQgdGhhdCBkYXRhIHRvIGFsbG93IGZvciB0aGUgc3RhdGVzIHRvIGJlIGNvbG9yIGNvZGVkIGJhc2VkIG9uIHRoZSBudW1iZXIgb2YgY2hhcmdpbmcgc3RhdGlvbnMgcGVyIHN0YXRlLiBUbyBkbyB0aGlzIHlvdSB3aWxsIHVzZSBhIGZ1bmN0aW9uIGNhbGxlZCBgYGBtZXJnZWBgYCBmcm9tIHRoZSBiYXNlICoqUioqIGZ1bmN0aW9ucyB0aGF0IHdpbGwgYWxsb3cgeW91IHRvIGNvbWJpbmUgdGhlIGluZm9ybWF0aW9uIGZyb20gdGhlICoqZXZzKiogYW5kICoqdXMqKiBpbnRvIGEgc2luZ2xlIGRhdGFzZXQgdGhhdCBjb250YWlucyBpbmZvcm1hdGlvbiBmcm9tIGJvdGggYmFzZWQgb24gYSBjb21tb24gdmFyaWFibGUuIFNvIHRvIHN0YXJ0IHlvdSB3aWxsIG5lZWQgdG8gZGV0ZXJtaW5lIHdoYXQgdmFyaWFibGUocykgYXJlIGNvbnRhaW5lZCB3aXRoaW4gZWFjaCBkYXRhc2V0LiBZb3UgaGF2ZSBzZWVuIGhvdyB0byBleGFtaW5lIGRhdGFzZXRzIHVzaW5nIGJvdGggYGBgaGVhZCgpYGBgIGFuZCBgYGBzdHIoKWBgYCBhbHJlYWR5IGluIHRoaXMgZXhlcmNpc2UuIENyZWF0ZSBhIG5ldyBjb2RlIGJsb2NrIGFuZCBleGFtaW5lIHRoZSBzdHJ1Y3R1cmUgb2YgZWFjaCBkYXRhc2V0LiBZb3Ugd2lsbCBzZWUgdGhhdCB0aGVyZSBpcyBhIGNvbHVtbiBmb3Igc3RhdGUgbmFtZSBpbiBlYWNoIGV4Y2VwdCB0aGV5IGFyZSBsYWJlbGVkIGRpZmZlcmVudGx5LiBUaGlzIGlzIGltcG9ydGFudCBpbmZvcm1hdGlvbiB5b3Ugd2lsbCBuZWVkIHRvIHByb3Blcmx5IGBgYG1lcmdlYGBgIHRoZSBkYXRhc2V0cy4NCg0KVG8gZG8gdGhpcyB5b3Ugd2lsbCBmaXJzdCBjcmVhdGUgYW4gb2JqZWN0ICgqKjwtKiopIHdpdGggYSBuZXcgbmFtZSwgdGhlbiB3aXRoIHRoZSBgYGBtZXJnZWBgYCBmdW5jdGlvbiBzZXQgdGhlIGZvbGxvd2luZyBhcmd1bWVudHM6DQoNCi0geCwgd2hpY2ggaXMgdGhlIGZpcnN0IGRhdGEgc2V0DQotIHksIHdoaWNoIGlzIHRoZSBzZWNvbmQgZGF0YXNldA0KLSBieS54LCBpZGVudGlmaWVzIHRoZSBjb2x1bW4gdG8gdXNlIGZvciB0aGUgbWVyZ2UgaW4geA0KLSBieS55LCBpZGVudGlmaWVzIHRoZSBjb2x1bW4gdG8gdXNlIGZvciB0aGUgbWVyZ2UgaW4geQ0KLSBhbGwgPSBUUlVFLCB3aGljaCB0ZWxscyB0aGUgZnVuY3Rpb24gdG8gcmV0YWluIGFsbCBkYXRhDQoNClNvIHlvdXIgZmluYWwgc2NyaXB0IHdpbGwgYmU6DQoNCmBgYHtyIG1lcmdlZCBkYXRhc2V0cywgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kc3RhdGVzIDwtIG1lcmdlKHggPSB1cywgeSA9IGV2cywgYnkueCA9ICJyZWdpb24iLCBieS55ID0gInN0YXRlIiwgYWxsID0gVFJVRSkNCmhlYWQoc3RhdGVzKQ0KYGBgDQoNCk5vdyB5b3Ugd2lsbCBzZWUgdGhlIGNvbHVtbnMgZm9yICoqZXZzKiogYW5kICoqYWJicmV2aWF0aW9uKiogaW5jbHVkZWQgaW4gdGhlICoqdXMqKiBkYXRhc2V0LiBUaGlzIG5ldyBkYXRhc2V0IHdpbGwgYmUgd2hhdCB5b3UgdXNlIHRvIHZpc3VhbGl6ZSB0aGUgaW5mb3JtYXRpb24gaW4gdGhlIG5leHQgc3RlcC4NCg0KPGJpZz48Yj5RdWVzdGlvbiBOby4gMjwvYj48L2JpZz4NCjxibG9ja3F1b3RlPg0KVXNpbmcgYGBgc3VtKHN0YXRlcylgYGAgaW4gYSBuZXcgY29kZSBjZWxsLCB3aGF0IGFyZSB0aGUgbGFyZ2VzdCBhbmQgc21hbGxlc3QgbnVtYmVyIG9mIGVsZWN0cmljIHZlaGljbGUgY2hhcmdpbmcgc3RhdGlvbnM/DQo8L2Jsb2NrcXVvdGU+DQoNCjwvZGV0YWlscz4NCg0KDQojIyBTdGVwIFRocmVlOiBUaGUgVmlzdWFsaXphdGlvbg0KDQpZb3Ugd2lsbCBsZWFybiBob3cgdG8gY3JlYXRlIGEgZ3JhcGhpY2FsIGRpc3BsYXkgb2YgeW91ciBkYXRhIHRoYXQgaW5jbHVkZXMgY2FydG9ncmFwaGljIGVsZW1lbnRzIHN1Y2ggYXMgbGVnZW5kLCBzY2FsZSBiYXIsIG5vcnRoIGFycm93LCBldGMuDQoNCjxkZXRhaWxzPjxzdW1tYXJ5PjxiaWc+VmlldyBkaXJlY3Rpb25zIGluIDxiPiBbQXJjR0lTIFByb117c3R5bGU9ImNvbG9yOiNmZjQ1MDAifSA8L2I+PC9zcGFuPjwvYmlnPjwvc3VtbWFyeT4NCg0KX0luc2VydCBUZXh0IEhlcmVfDQoNCjwvZGV0YWlscz4NCjxocj48L2hyPg0KDQo8ZGV0YWlscz48c3VtbWFyeT48YmlnPlZpZXcgZGlyZWN0aW9ucyBpbiA8Yj4gW1FHSVNde3N0eWxlPSJjb2xvcjojMDA2NDAwIn0gPC9iPjwvc3Bhbj48L2JpZz48L3N1bW1hcnk+DQoNCk5vdyBpdCdzIHRpbWUgdG8gdHVybiB5b3VyIGRhdGEgaW50byBhIG1hcC4gRnJvbSB0aGUgbWVudSBiYXIgaW4gZWl0aGVyIG1hY09TIG9yIFBDIGNsaWNrIF9Qcm9ncmFtID4gTmV3IFByaW50IExheW91dF8uIFRoaXMgd2lsbCBvcGVuIGEgbmV3IHdpbmRvdyB3aGVyZSB5b3Ugd2lsbCBhZGQgdGhlIGRhdGEsIHRpdGxlLCBsZWdlbmQsIG5vcnRoIGFycm93LCBzY2FsZSBiYXIsIGFuZCB5b3VyIG5hbWUgYW5kIGRhdGUuDQoNCjxwIGFsaWduPSJjZW50ZXIiPjxkaXYgY2xhc3M9Inpvb20iPiA8aW1nIHNyYz0gIkltYWdlcy9xZ2lzLW5ldy1wcmludC1sYXllci5wbmciIGFsdD0iTmV3IFByaW50IExheW91dCIgc3R5bGU9IndpZHRoOjEwMCUiPjwvZGl2PjwvcD4NCg0KPC9kZXRhaWxzPg0KPGhyPjwvaHI+DQoNCjxkZXRhaWxzPjxzdW1tYXJ5PjxiaWc+VmlldyBkaXJlY3Rpb25zIGluIDxiPiBbUl17c3R5bGU9ImNvbG9yOiM2NDk1RUQifSA8L2I+PC9zcGFuPjwvYmlnPjwvc3VtbWFyeT4NCg0KV2l0aCB0aGlzIG5ldyBkYXRhc2V0IHlvdSBhcmUgbm93IHJlYWR5IHRvIGNyZWF0ZSBhIG1hcCB0byBleGFtaW5lIHRoZSBkaXN0cmlidXRpb24gb2YgZWxlY3RyaWMgdmVoaWNsZSBjaGFyZ2luZyBzdGF0aW9ucyBhY3Jvc3MgdGhlIGNvdW50cnkuIEluIHRoZSBzdGVwIG9uZSB5b3UgdXNlZCBhIHZlcnkgc2ltcGxlIHNjcmlwdCB0byBkaXNwbGF5IHRoZSAqKnVzKiogZGF0YS4NCg0KYGBgDQpnZ3Bsb3QodXMpICsgDQogIGdlb21fcG9seWdvbihhZXMoeD1sb25nLCB5PWxhdCwgZ3JvdXA9Z3JvdXApLCBjb2xvciA9ICJ3aGl0ZSIpDQpgYGANCg0KQSBzaW1pbGFyIHNjcmlwdCB3b3VsZCBhbGxvdyB5b3UgdG8gcXVpY2tseSB2aXN1YWxpemUgdGhlIGRhdGEgYGBgZ2dwbG90KHN0YXRlcykgKyBnZW9tX3BvbHlnb24oYWVzKHg9bG9uZywgeT1sYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gZXZzX2NvdW50KSwgY29sb3IgPSAid2hpdGUiKWBgYCwgaG93ZXZlciwgeW91IG5lZWQgdG8gYWRkIGEgbnVtYmVyIG9mIGVsZW1lbnRzIGluIG9yZGVyIHRvIGNyZWF0ZSBhIG1hcCBzdWNoIGFzIGEgc2NhbGUgYmFyLCBub3J0aCBhcnJvdywgdGl0bGUsIGV0Yy4gQWRkaXRpb25hbGx5LCB5b3UgY2FuIGN1c3RvbWl6ZSBvdGhlciBjb21wb25lbnRzIHRvIHByb3ZpZGUgYSBiZXR0ZXIgb3ZlcmFsbCB2aXN1YWxpemF0aW9uLg0KDQpFYXJsaWVyIGluIHRoZSBub3RlYm9vayB3ZSBpbnN0YWxsZWQgdGhlIGBgYGdnc25gYGAgcGFja2FnZS4gVGhpcyBwYWNrYWdlIGFsbG93cyB5b3UgdG8gYWRkICJub3J0aCBzeW1ib2xzIGFuZCBzY2FsZSBiYXJzIGZvciBtYXBzIGNyZWF0ZWQgd2l0aCAnZ2dwbG90Micgb3IgJ2dnbWFwJy4iIFNvIHlvdSBjYW4gYnVpbGQgb24gdGhlIHNjcmlwdCBhYm92ZSB0byBjcmVhdGUgYSBtYXAgb2YgdGhlIGluZm9ybWF0aW9uIGluIHRoZSAqKnN0YXRlcyoqIGRhdGFzZXQuIFRvIGJlZ2luLCBydW4gdGhlIHNjcmlwdCBhYm92ZSB3aXRoIHRoZSBhZGRlZCAqKmZpbGwqKiBhcmd1bWVudCB0byBzZWUgdGhlIG91dGNvbWU6DQoNCmBgYHtyIGJhc2ljIGV2cyBtYXAsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGxvdChzdGF0ZXMpICsgZ2VvbV9wb2x5Z29uKGFlcyh4PWxvbmcsIHk9bGF0LCBncm91cD1ncm91cCwgZmlsbCA9IGV2c19jb3VudCksIGNvbG9yID0gIndoaXRlIikNCmBgYA0KDQpPbmUgdGhpbmcgeW91IHdpbGwgbm90aWNlIGlzIHRoYXQgdGhlIGNhdGVnb3JpZXMgYXJlIHZlcnkgZGlmZmljdWx0IHRvIGRpc3Rpbmd1aXNoLiBCZWNhdXNlIHlvdSBoYXZlIHdpZGUgcmFuZ2luZyBkYXRhIGluIHRoZSBfZXZzX2NvdW50XyBjb2x1bW4gb25seSB0aGUgbGFyZ2VzdCB2YWx1ZSBpcyBzaG93aW5nLiBBIHNpbXBsZSBmaXggdG8gdGhpcyB3b3VsZCBiZSB0byB0YWtlIHRoZSBjb21tb24gbG9nYXJpdGhtIG9mIHRoZSBkYXRhIHRvIHN0YW5kYXJkaXplIHRoZSBkYXRhIGJ5IHJlbW92aW5nIHRoZSBza2V3bmVzcyB0b3dhcmRzIGxhcmdlIHZhbHVlcy4gVGhlIGZ1bmN0aW9uIGBgYHNjYWxlLXZpcmlkaXNgYGAgc2NhbGVzIHRoZSBkYXRhIGFuZCBwcm92aWRlcyBhIGNvbG9yIG1hcCBkZXNpZ25lZCB0byBiZSBwZXJjZWl2ZWQgYnkgdmlld2VycyB3aXRoIGNvbW1vbiBmb3JtcyBvZiBjb2xvciBibGluZG5lc3MuIFNvIHlvdSBjYW4gYWRkIGBgYHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJEIiwgdHJhbnMgPSAibG9nMTAiKWBgYCB0byB0aGUgc2NyaXB0IGFib3ZlIHdoZXJlOg0KDQotIHNjYWxlX2ZpbGxfdmlyaWRpc19jIGlzIGEgZmlsbCBwYXR0ZXJuIGZvciBjb250aW51b3VzIGRhdGENCi0gb3B0aW9uID0gIkQiIGlzIHRoZSBkZWZhdWx0IGNvbG9yIG9wdGlvbg0KICAtIFRoZXJlIGFyZSBmaXZlIGNvbG9yIG9wdGlvbnMgYXZhaWxhYmxlIHdpdGggdGhpcyBmdW5jdGlvbg0KICAgIC0gQSA9IG1hZ21hDQogICAgLSBCID0gaW5mZXJubw0KICAgIC0gQyA9IHBsYXNtYQ0KICAgIC0gRCA9IHZpcmlkaXMNCiAgICAtIEUgPSBjaXZpZGlzDQotIHRyYW5zID0gImxvZzEwIiB0cmFuc2Zvcm1zIHRoZSBkYXRhIHVzaW5nIGNvbW1vbiBsb2dhcml0aG0sIG90aGVyIG9wdGlvbnMgYXJlIGF2YWlsYWJsZTsgc2VlIGRvY3VtZW50YXRpb24NCg0KVGhlIG5ldyBzY3JpcHQgc2hvdWxkIG5vdyBsb29rIGxpa2UgdGhpczoNCg0KYGBge3IgbG9nIGV2cyBtYXAsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGxvdChzdGF0ZXMpICsgDQogIGdlb21fcG9seWdvbihhZXMoeD1sb25nLCB5PWxhdCwgZ3JvdXA9Z3JvdXAsIGZpbGwgPSBldnNfY291bnQpLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gIkQiLCB0cmFucyA9ICJsb2cxMCIpDQpgYGANCg0KTm93IHRoYXQgeW91IGFyZSBhYmxlIHRvIHZpc3VhbGl6ZSB0aGUgc2VwYXJhdGlvbnMgaW4gdGhlIGRhdGEgeW91IGNhbiBhZGQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbi4gWW91IGNhbiBzdGFydCB3aXRoIGN1c3RvbWl6aW5nIHRoZSBsYWJlbHMsIG1hcCB0aXRsZSwgYW5kIGxlZ2VuZCB0aXRsZS4gVGhpcyBjYW4gYWxsIGJlIGNvbXBsZXRlZCBieSBhZGRpbmcgYSBzaW5nbGUgbGluZSBvZiBjb2RlIGNvbnRhaW5pbmcgYWxsIG9mIHRoZSB0ZXh0IGluZm9ybWF0aW9uIGZvciB0aG9zZSBpdGVtczoNCg0KYGBge3IgbG9nIG1hcCB3IHRpdGxlcywgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZ2dwbG90KHN0YXRlcykgKyANCiAgICBnZW9tX3BvbHlnb24oYWVzKHg9bG9uZywgeT1sYXQsIGdyb3VwPWdyb3VwLCBmaWxsID0gZXZzX2NvdW50KSwgY29sb3IgPSAid2hpdGUiKSArDQogIHNjYWxlX2ZpbGxfdmlyaWRpc19jKG9wdGlvbiA9ICJEIiwgdHJhbnMgPSAibG9nMTAiKSArIA0KICBsYWJzKHg9IkxvbmdpdHVkZSIseT0iTGF0aXR1ZGUiLCB0aXRsZT0iTnVtYmVyIG9mIEVsZWN0cmljIFZlaGljbGUgQ2hhcmdpbmcgU3RhdGlvbnMgUGVyIFN0YXRlIiwgZmlsbCA9ICJOby4gb2YgU3RhdGlvbnMiKQ0KYGBgDQoNCkZlZWwgZnJlZSB0byBlZGl0IHRoZSBsYWJlbCBuYW1lcyBhbmQgdGhlIGNvbG9yIG9wdGlvbiBpbiB0aGUgc2NyaXB0IHRvIHByb3ZpZGUgeW91ciBvd24gY3VzdG9taXphdGlvbnMuIE5leHQgeW91IG5lZWQgdG8gYWRkIGEgc2NhbGUgYmFyIGFuZCBub3J0aCBhcnJvdy4gVG8gdmlldyB0aGUgYXZhaWxhYmxlIG9wdGlvbnMgZm9yIHRoZSBub3J0aCBhcnJvdyB0eXBlIGBgYG5vcnRoU3ltYm9scygpYGBgIGludG8gYSBuZXcgY29kZSBibG9jay4gVGhlIG51bWVyaWMgdmFsdWVzIGJlbG93IGVhY2ggc3ltYm9sIHdpbGwgYmUgdXNlZCBpbiB0aGUgc2NyaXB0IHRvIGlkZW50aWZ5IHRoZSBzcGVjaWZpYyBzdHlsZSB5b3UgY2hvb3NlLiBCZWNhdXNlIHRoZSBub3J0aCBhcnJvdywgYGBgbm9ydGhgYGAsIGlzIHNwZWNpZmljYWxseSByZWxhdGVkIHRvIHRoZSBtYXAgZGF0YSB5b3UgbmVlZCB0byBwcm92aWRlIHRoZSBmb2xsb3dpbmcgYXJndW1lbnRzOg0KDQotIGRhdGFzZXQNCi0gc3ltYm9sLCBpZGVudGlmaWVkIGJ5IHRoZSBudW1lcmljYWwgdmFsdWUgZnJvbSBgYGBub3J0aFN5bWJvbHMoKWBgYA0KLSBsb2NhdGlvbiwgaW5kaWNhdGluZyB3aGVyZSB0byBiYXNlIHRoZSBsb2NhdGlvbiBvbiB0aGUgbWFwDQotIGFuY2hvciwgY29vcmRpbmF0ZXMgZm9yIHRoZSBzeW1ib2wgcG9zaXRpb24gb24gdGhlIG1hcCAoYmFzZWQgb2ZmIHRoZSBsb2NhdGlvbikNCi0gc2NhbGUsIHRoZSBzeW1ib2wgc2l6ZSBhcyBhIHByb3BvcnRpb24gb2YgdGhlIG1hcCBzaXplIA0KDQpTbyB5b3VyIG5ldyBzY3JpcHQgd2lsbCBsb29rIGxpa2U6DQoNCmBgYHtyIG1hcCB0aXRsZXMgbm9ydGgsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGxvdChzdGF0ZXMpICsgDQogIGdlb21fcG9seWdvbihhZXMoeD1sb25nLCB5PWxhdCwgZ3JvdXA9Z3JvdXAsIGZpbGwgPSBldnNfY291bnQpLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gIkQiLCB0cmFucyA9ICJsb2cxMCIpICsgDQogIGxhYnMoeD0iTG9uZ2l0dWRlIix5PSJMYXRpdHVkZSIsIHRpdGxlPSJOdW1iZXIgb2YgRWxlY3RyaWMgVmVoaWNsZSBDaGFyZ2luZyBTdGF0aW9ucyBQZXIgU3RhdGUiLCBmaWxsID0gIk5vLiBvZiBTdGF0aW9ucyIpICsNCiAgbm9ydGgoc3RhdGVzLCBsb2NhdGlvbiA9ICJib3R0b21sZWZ0Iiwgc2NhbGUgPSAwLjA1LCBzeW1ib2wgPSAxMiwgYW5jaG9yID0gYyh4PSAtNzAsIHk9IDI1KSkNCmBgYA0KSW4gdGhpcyBleGFtcGxlLCBgYGBsb2NhdGlvbiA9ICJib3R0b21sZWZ0ImBgYCBtZWFucyB0aGUgbG9jYXRpb24gb2YgdGhlIF9ub3J0aCBhcnJvd18gd2lsbCBiZSBiYXNlZCBmcm9tIHRoZSBib3R0b20gbGVmdCBvZiB0aGUgc3ltYm9sIGFuZCBgYGFuY2hvciA9IGMoeCA9IC03MCwgeSA9IDI1KWBgYCBpcyB0aGUgZ2VvZ3JhcGhpYyBsb2NhdGlvbiBvbiB0aGUgbWFwIHRvIGRyYXcgdGhlIHN5bWJvbC4gRm9yIGV4YW1wbGUsIGlmIHRoZSBfYW5jaG9yc18gd2VyZSBzZXQgYXQgLTEwMCBhbmQgNDAgdGhlIHN5bWJvbCB3b3VsZCBiZSBkcmF3IG9uIHRoZSBOZWJyYXNrYS9LYW5zYXMgYm9yZGVyLiBGZWVsIGZyZWUgdG8gYWRqdXN0IHRoZSBhbmNob3IgcG9pbnRzIHRvIGRyYXcgdGhlIG5vcnRoIGFycm93IGluIHlvdXIgcHJlZmVycmVkIGxvY2F0aW9uLg0KDQpOb3cgeW91IG5lZWQgdG8gYWRkIGEgc2NhbGUgYmFyLiBNYW55IG9mIHRoZSBhcmd1bWVudHMgdXNlZCBmb3IgdGhlIG5vcnRoIGFycm93IGFyZSBkdXBsaWNhdGVkIGZvciBgYGBzY2FsZWJhcmBgYA0KDQotIGRhdGFzZXQNCi0gbG9jYXRpb24sIGluZGljYXRpbmcgd2hlcmUgdG8gYmFzZSB0aGUgbG9jYXRpb24gb24gdGhlIG1hcA0KLSBhbmNob3IsIGNvb3JkaW5hdGVzIGZvciB0aGUgc3ltYm9sIHBvc2l0aW9uIG9uIHRoZSBtYXAgKGJhc2VkIG9mZiB0aGUgbG9jYXRpb24pDQotIGRpc3RhbmNlIGZvciBlYWNoIHVuaXQgb2YgdGhlIHNjYWxlIGJhcg0KLSB1bml0IG9mIG1lYXN1cmVtZW50IHN1Y2ggYXMgbWksIGttLCBldGMuDQotIHRyYW5zZm9ybSAoVFJVRS9GQUxTRSksIGFzc3VtZXMgdGhlIGNvb3JkaW5hdGVzIGFyZSBpbiBkZWNpbWFsIGRlZ3JlZXMNCi0gbW9kZWwsIGNob2ljZSBvZiBlbGxpcHNvaWQ7IHdoaWNoIHdpbGwgYmUgZGlzY3Vzc2VkIGxhdGVyIGluIHRoZSBzZW1lc3Rlcg0KLSBzdC5zaXplLCBzY2FsZSBiYXIgc2l6ZQ0KLSBzdC5kaXN0LCBkaXN0YW5jZSBiZXR3ZWVuIHRoZSBzY2FsZSBiYXIgYW5kIHRoZSBzY2FsZSBiYXLigJlzIHRleHQsIGFzIGEgcHJvcG9ydGlvbiBvZiB0aGUgeSBheGlzDQoNCmBgYHtyIG1hcCB0aXRsZXMgbm9ydGggc2NhbGUsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmdncGxvdChzdGF0ZXMpICsgDQogIGdlb21fcG9seWdvbihhZXMoeD1sb25nLCB5PWxhdCwgZ3JvdXA9Z3JvdXAsIGZpbGwgPSBldnNfY291bnQpLCBjb2xvciA9ICJ3aGl0ZSIpICsNCiAgc2NhbGVfZmlsbF92aXJpZGlzX2Mob3B0aW9uID0gIkQiLCB0cmFucyA9ICJsb2cxMCIpICsgDQogIGxhYnMoeD0iTG9uZ2l0dWRlIix5PSJMYXRpdHVkZSIsIHRpdGxlPSJOdW1iZXIgb2YgRWxlY3RyaWMgVmVoaWNsZSBDaGFyZ2luZyBTdGF0aW9ucyBQZXIgU3RhdGUiLCBmaWxsID0gIk5vLiBvZiBTdGF0aW9ucyIpICsNCiAgbm9ydGgoc3RhdGVzLCBsb2NhdGlvbiA9ICJib3R0b21sZWZ0Iiwgc2NhbGUgPSAwLjA1LCBzeW1ib2wgPSAxMiwgYW5jaG9yID0gYyh4PSAtNzAsIHk9IDI1KSkgKyANCiAgc2NhbGViYXIoc3RhdGVzLCBkaXN0ID0gMjUwLCBkaXN0X3VuaXQgPSAibWkiLCB0cmFuc2Zvcm0gPSBUUlVFLCBtb2RlbCA9ICJXR1M4NCIsIGxvY2F0aW9uID0gImJvdHRvbWxlZnQiLCBzdC5kaXN0ID0gMC4wNSwgc3Quc2l6ZSA9IDIsIGFuY2hvciA9IGMoeD0tMTI1LHk9MjcpKQ0KYGBgDQoNCkFzIHdpdGggYWxsIG9mIHRoZSBvdGhlciBjdXN0b21pemF0aW9ucyBhYm92ZSwgZmVlbCBmcmVlIHRvIGFkanVzdCB0aGUgdW5pdHMsIGRpc3RhbmNlLCB0ZXh0IGRpc3RhbmNlLCBhbmQgc2l6ZSBiYXNlZCBvbiB5b3VyIG93biBzdHlsZS4NCg0KRmluYWxseSwgeW91IHdpbGwgbmVlZCB0byBhZGQgdGV4dCB0byB0aGUgbWFwIHRvIGluZGljYXRlIHRoZSBuYW1lIG9mIHRoZSBwZXJzb24gd2hvIGNyZWF0ZWQgdGhlIG1hcCBhbmQgdGhlIGRhdGUuIEluIHRoZSBmdXR1cmUgeW91IHdpbGwgcG9zc2libHkgaW5jbHVkZSByZWZlcmVuY2VzIG9yIG90aGVyIHRleHQgYmFzZWQgaW5mb3JtYXRpb24uIFRoZXJlIGFyZSBhIG51bWJlciBvZiBkaWZmZXJlbnQgd2F5cyB5b3Ugd2lsbCBleHBsb3JlIGZvciBhZGRpbmcgdGV4dCBpbmZvcm1hdGlvbiB0byB5b3VyIG1hcHMsIHN1Y2ggYXMgYGBgY2FwdGlvbiA9IGBgYCBpbiBsYWJzLCBidXQgZm9yIHRoaXMgZXhhbXBsZSB5b3Ugd2lsbCB1c2UgYGBgYW5ub3RhdGUoKWBgYC4gU2ltaWxhciB0byB0aGUgbm9ydGggYXJyb3cgYW5kIHNjYWxlIGJhciwgdGhlcmUgd2lsbCBiZSBhDQoNCi0gX3hfIGFuZCBfeV8gYXJndW1lbnQgdG8gc2V0IHRoZSBsb2NhdGlvbg0KLSBzaXplIHRvIGluZGljYXRlIHRoZSBmb250IHNpemUNCi0gbGFiZWwgZm9yIHRoZSB0ZXh0IHlvdSB3aXNoIHRvIGluY2x1ZGU7IHRvIGNyZWF0ZSBhIGNoYXJhY3RlciByZXR1cm4gdG8gbW92ZSB0ZXh0IHRvIGEgbmV3IGxpbmUgeW91IHNob3VsZCB1c2UgIlxcbiIgd2hlcmUgeW91IHdhbnQgdGhlIHRleHQgdG8gbW92ZSB0byBhIG5ldyBsaW5lDQoNCllvdXIgZmluYWwgc2NyaXB0IHNob3VsZCBub3cgbG9vayBzaW1pbGFyIHRvIHRoaXM6DQoNCmBgYHtyIGZpbmFsIG1hcCwgZWNobz1UUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZ2dwbG90KHN0YXRlcykgKyANCiAgZ2VvbV9wb2x5Z29uKGFlcyh4PWxvbmcsIHk9bGF0LCBncm91cD1ncm91cCwgZmlsbCA9IGV2c19jb3VudCksIGNvbG9yID0gIndoaXRlIikgKw0KICBzY2FsZV9maWxsX3ZpcmlkaXNfYyhvcHRpb24gPSAiRCIsIHRyYW5zID0gImxvZzEwIikgKyANCiAgbGFicyh4PSJMb25naXR1ZGUiLHk9IkxhdGl0dWRlIiwgdGl0bGU9Ik51bWJlciBvZiBFbGVjdHJpYyBWZWhpY2xlIENoYXJnaW5nIFN0YXRpb25zIFBlciBTdGF0ZSIsIGZpbGwgPSAiTm8uIG9mIFN0YXRpb25zIikgKw0KICBub3J0aChzdGF0ZXMsIGxvY2F0aW9uID0gImJvdHRvbWxlZnQiLCBzY2FsZSA9IDAuMDUsIHN5bWJvbCA9IDEyLCBhbmNob3IgPSBjKHg9IC03MCwgeT0gMjUpKSArIA0KICBzY2FsZWJhcihzdGF0ZXMsIGRpc3QgPSAyNTAsIGRpc3RfdW5pdCA9ICJtaSIsIHRyYW5zZm9ybSA9IFRSVUUsIG1vZGVsID0gIldHUzg0IiwgbG9jYXRpb24gPSAiYm90dG9tbGVmdCIsIHN0LmRpc3QgPSAwLjA1LCBzdC5zaXplID0gMiwgYW5jaG9yID0gYyh4PS0xMjUseT0yNykpICsNCiAgYW5ub3RhdGUoInRleHQiLCB4ID0gLTkwLCB5ID0gMjUsIGxhYmVsID0gIllvdXIgTmFtZSBcbiBUaGUgRGF0ZSIsIHNpemUgPSAyKQ0KYGBgDQoNClRoZXJlIGlzIGFuIGV4aGF1c3RpdmUgYW1vdW50IG9mIG1vZGlmaWNhdGlvbnMgdGhhdCBjYW4gYmUgYXBwbGllZCB0byB0aGUgbWFwIGFib3ZlLCBidXQgZm9yIG5vdyB5b3UgaGF2ZSB0aGUgbWluaW11bSBpbmZvcm1hdGlvbiByZXF1aXJlZCB0byBjcmVhdGUgYSBtYXAgb2Ygc2ltaWxhciBraW5kcyBvZiBkYXRhLiBJbiBmdXR1cmUgZXhlcmNpc2VzIHlvdSB3aWxsIHVzZSB2YXJpb3VzIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSB0aGUgbG9vayBvZiB5b3VyIG1hcHMuIA0KDQo8Yj48YmlnPlF1ZXN0aW9uIE5vLiAzPC9iaWc+PC9iPg0KPGJsb2NrcXVvdGU+DQpIb3cgZG9lcyB0aGUgX2Rpc3QgPSBfICZuYnNwO2FyZ3VtZW50IGluIHRoZSBgYGBzY2FsZWJhcmBgYCBmdW5jdGlvbiByZWxhdGUgc3BlY2lmaWNhbGx5IHRvIHRoZSBkaXN0YW5jZSBvZiB0aGUgc2NhbGUgYmFyIG9uIHlvdXIgbWFwPyBIb3cgd291bGQgY2hhbmdpbmcgdGhlIHZhbHVlIGFsdGVyIHRoZSBhcHBlYXJhbmNlPw0KPC9ibG9ja3F1b3RlPg0KDQo8L2RldGFpbHM+DQoNCiMjIFN0ZXAgRm91cjogWW91ciBUdXJuDQoNCkFmdGVyIGEgcmFzaCBvZiBzZXZlcmUgd2VhdGhlciBvdmVyIHRoZSBwYXN0IGZldyB5ZWFycyB0aGUgTW9udGdvbWVyeSBDb3VudHkgRW1lcmdlbmN5IE1hbmFnZW1lbnQgQWdlbmN5IGhhcyBhc2tlZCB5b3UgdG8gcHJvdmlkZSBhIG1hcCBkZXRhaWxpbmcgdGhlIG51bWJlciBvZiByZXBvcnRlZCB0b3JuYWRvZXMgaW4gZWFjaCBUZW5uZXNzZWUgY291bnR5IG92ZXIgdGhlIHBhc3Qgc2V2ZXJhbCBkZWNhZGVzLiBUaGlzIGluZm9ybWF0aW9uIHdpbGwgYmUgc2hhcmVkIHdpdGggbmVpZ2hib3JpbmcgY291bnRpZXMgaW4gbWlkZGxlIFRlbm5lc3NlZSBhcyBhIHBhcnQgb2Ygc2V2ZXJlIHdlYXRoZXIgZWR1Y2F0aW9uIGNhbXBhaWduIGRlc2lnbmVkIHRvIGluZm9ybSBjb21tdW5pdGllcyBhYm91dCB0aGUgcmlzayBvZiB0b3JuYWRvZXMgaW4gdGhlIHJlZ2lvbi4gVGhlIG1hcCBzaG91bGQgaW5jbHVkZSBhbGwgb2YgdGhlIGVsZW1lbnRzIGluY2x1ZGVkIG9uIHlvdXIgcHJldmlvdXMgbWFwIG9mIGVsZWN0cmljIHZlaGljbGUgY2hhcmdpbmcgc3RhdGlvbnMgc3VjaCBhczoNCg0KLSBUaXRsZQ0KLSBTY2FsZQ0KLSBOb3J0aCBBcnJvdw0KLSBMZWdlbmQNCi0gTmFtZS9EYXRlIG9mIENhcnRvZ3JhcGhlcg0KDQpTb2Z0d2FyZSBzcGVjaWZpYyBkaXJlY3Rpb25zIGNhbiBiZSBmb3VuZCBmb3IgZWFjaCBzdGVwIGJlbG93LiBQbGVhc2Ugc3VibWl0IHRoZSBhbnN3ZXIgdG8gdGhlIHF1ZXN0aW9ucyB5b3UgYW5zd2VyZWQgYWJvdmUgYXMgd2VsbCBhcyB5b3VyIGZpbmFsIHRvcm5hZG8gbWFwIGJ5IHRoZSBkdWUgZGF0ZS4NCg0KPGRldGFpbHM+PHN1bW1hcnk+PGJpZz5WaWV3IGRpcmVjdGlvbnMgaW4gPGI+IFtBcmNHSVMgUHJvXXtzdHlsZT0iY29sb3I6I2ZmNDUwMCJ9IDwvYj48L3NwYW4+PC9iaWc+PC9zdW1tYXJ5Pg0KDQpfSW5zZXJ0IFRleHQgSGVyZV8NCg0KPC9kZXRhaWxzPg0KPGhyPjwvaHI+DQoNCjxkZXRhaWxzPjxzdW1tYXJ5PjxiaWc+VmlldyBkaXJlY3Rpb25zIGluIDxiPiBbUUdJU117c3R5bGU9ImNvbG9yOiMwMDY0MDAifSA8L2I+PC9zcGFuPjwvYmlnPjwvc3VtbWFyeT4NCg0KX0luc2VydCBUZXh0IEhlcmVfDQoNCjwvZGV0YWlscz4NCjxocj48L2hyPg0KDQo8ZGV0YWlscz48c3VtbWFyeT48YmlnPlZpZXcgZGlyZWN0aW9ucyBpbiA8Yj4gW1Jde3N0eWxlPSJjb2xvcjojNjQ5NUVEIn0gPC9iPjwvc3Bhbj48L2JpZz48L3N1bW1hcnk+DQoNClRoaXMgcG9ydGlvbiBvZiB0aGUgZXhlcmNpc2UgaXMgbWVhbnQgdG8gcmVpbmZvcmNlIHRoZSBza2lsbHMgeW91IGxlYXJuZWQgaW4gdGhlIHBhcnQgb2YgdGhlIGxhYi4gVGhlIHN0ZXBzIHlvdSB3aWxsIHRha2UgdG8gY29tcGxldGUgeW91ciBmaW5hbCBtYXAgd2lsbCBiZSB0bzoNCg0KMS4gQ3JlYXRlIGFuIG9iamVjdCBmcm9tIHRoZSB0b3JuYWRvZXMgZGF0YXNldA0KMi4gT2J0YWluIGEgZGF0YXNldCBvZiBUZW5uZXNzZWUgY291bnRpZXMNCjMuIERldGVybWluZSB3aGljaCBjb2x1bW5zIGNhbiBiZSB1c2VkIHRvIGBgYG1lcmdlYGBgIHRoZSBkYXRhc2V0cw0KNC4gTWFwIG91dCB0aGUgZGF0YSB1c2luZyBgYGBnZ3Bsb3RgYGANCg0KDQpUbyBiZWdpbiB0aGUgZXhlcmNpc2UgeW91IHdpbGwgbmVlZCB0aGlzIFVSTCB0byB0aGUgY29tbWEgZGVsaW1pdGVkIGRhdGFzZXQ6DQoNCmh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9jaHJpc21nZW50cnkvR0lTMS1FeGVyY2lzZS0yL21haW4vRGF0YS90bl90b3JuYWRvZXMuY3N2DQoNClRoaXMgZGF0YSByZXByZXNlbnRzIHRoZSBudW1iZXIgb2YgcmVwb3J0ZWQgdG9ybmFkb2VzIGluIGVhY2ggY291bnR5IGZyb20gMTk1MC0yMDIwLiBBcyBpbiBzdGVwIG9uZSBvZiB0aGUgZXhlcmNpc2UsIHlvdSBjYW4gdXNlIHRoZSAqKjwtKiogb3BlcmF0b3IgdG8gY3JlYXRlIGEgbmV3IG9iamVjdCBhbmQgdGhlIGBgYHJlYWQuY3N2KClgYGAgZnVuY3Rpb24gd2l0aCB0aGUgbGluayB0byB0aGUgZGF0YXNldCB0byBpbXBvcnQgdGhlIGRhdGEuIFJlbWVtYmVyIHlvdSBjYW4gdXNlIGBgYGhlYWQoKWBgYCBvciBgYGBzdHIoKWBgYCB0byBleGFtaW5lIHRoZSBpbmZvcm1hdGlvbi4NCg0KVG8gb2J0YWluIGNvdW50eSBpbmZvcm1hdGlvbiBmb3IgdGhlIFN0YXRlIG9mIFRlbm5lc3NlZSB5b3Ugc2hvdWxkIHVzZSB0aGUgZm9sbG93aW5nIHNjcmlwdDoNCg0KYGBge3IgdGVubmVzc2VlLCBlY2hvID0gVFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnRuIDwtIG1hcF9kYXRhKCdjb3VudHknLCByZWdpb24gPSAidGVubmVzc2VlIikNCmBgYA0KDQpJZiB5b3Ugc2VhcmNoIGZvciBfbWFwX2RhdGFfIGluIHRoZSAqKmdncGxvdDIqKiBbZG9jdW1lbnRhdGlvbl0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2dncGxvdDIvZ2dwbG90Mi5wZGYpIHlvdSB3aWxsIGZpbmQgYW4gZXhhbXBsZSBvZiBhIHNjcmlwdCB1c2VkIHRvIGlzb2xhdGUgaW5mb3JtYXRpb24gZm9yIHRoZSBTdGF0ZSBvZiBJb3dhIHRoYXQgY2FuIGJlIGFkYXB0ZWQgZm9yIGFueSBzdGF0ZSBpbiB0aGUgZGF0YXNldC4gUmVtZW1iZXIgd2hlbiB3b3JraW5nIHdpdGggc2NyaXB0cywgR29vZ2xlIGlzIHlvdXIgZnJpZW5kISBBbGwgaXQgcmVxdWlyZXMgaXMgYXNraW5nIHRoZSBjb3JyZWN0IHF1ZXN0aW9uIHRvIGZpbmQgc29tZSBleGFtcGxlIGNvZGUgb25saW5lIHRoYXQgY2FuIGhlbHAgZ3VpZGUgeW91LiBUaGVyZSBhcmUgbnVtZXJvdXMgcG9zc2libGUgYW5zd2VycyB0byB0aGUgc2FtZSBwcm9ibGVtIHNvIGRvbid0IGhlc2l0YXRlIHRvIHRyeSBvdGhlciBtZXRob2RzLg0KDQpVc2luZyB0aGUgZXhhbXBsZSBjb2RlIGZyb20gc3RlcCB0d28sIHlvdSB3aWxsIG5lZWQgdG8gYGBgbWVyZ2VgYGAgdGhlIHR3byBkYXRhc2V0cyBpbnRvIGEgbmV3IG9iamVjdCBiYXNlZCBvbiBhIGNvbW1vbiB2YXJpYWJsZSBzdWNoIGFzIDxzbWFsbD48aT5IaW50Li4uaGludDwvaT48L3NtYWxsPiBjb3VudHkgbmFtZS4NCg0KRmluYWxseSwgYnkgYWRhcHRpbmcgdGhlIGBgYGdncGxvdGBgYCBjb2RlIGluIHN0ZXAgZm91ciwgeW91IGNhbiBtYXAgdGhlIGluZm9ybWF0aW9uIGZvciBfdG9ybmFkb19jb3VudF8gZm9yIGVhY2ggY291bnR5IGluIFRlbm5lc3NlZS4gSW4gb3JkZXIgdG8gbGltaXQgdGhlIHNjb3BlIG9mIHlvdXIgbWFwIHRvIGp1c3QgdGhlIHN0YXRlIHlvdSBzaG91bGQgYWRkIHRoZSBmb2xsb3dpbmcgc2NyaXB0IHRvIHlvdXIgbW9kaWZpZWQgYGBgZ2dwbG90YGBgIGNvZGUgZnJvbSBhYm92ZToNCg0KYGBgDQpjb29yZF9maXhlZCh4bGltID0gYygtOTAsLTgyKSwgeWxpbSA9IGMoMzUsIDM3KSkNCmBgYA0KDQpUaGUgYGBgY29vcmRfZml4ZWQoKWBgYCBmdW5jdGlvbiBsaW1pdHMgdGhlIGF4ZXMgYmFzZWQgb24gc3BlY2lmaWVkIHZhbHVlcy4gVGhlIHZhbHVlcyBhcmUgYmFzZWQgb24gdGhlIHVuaXRzIG9mIG1lYXN1cmUgb2YgdGhlIGRhdGEuIEluIHRoaXMgY2FuIHlvdSBzZWUgd2hlcmUgdGhlICoqeCBheGlzKiogaXMgbGltaXRlZCAoX3hsaW1fKSBmcm9tIC04MiZkZWc7IHRvIC05MCZkZWc7IHdlc3QgbG9uZ2l0dWRlIGFuZCB0aGUgKip5IGF4aXMqKiBpcyBsaW1pdGVkIChfeWxpbV8pIGZyb20gMzUmZGVnOyB0byAzNyZkZWc7IG5vcnRoIGxhdGl0dWRlLiBJZiB5b3Ugb21pdCB0aGlzIHNjcmlwdCB5b3VyIG1hcCB3aWxsIGxpa2VseSBoYXZlIGEgInNtYXNoZWQiIGFwcGVhcmFuY2UuIEZvciBjcmVhdGluZyBtYXBzIGluICoqUioqIGl0IGlzIGdlbmVyYWxseSBhZHZpc2FibGUgdG8gc2V0IHRoZSBfeF8gYW5kIF95XyBjb29yZGluYXRlcyB0byBlbnN1cmUgcHJvcGVyIGRpc3BsYXkgb2YgeW91ciBkYXRhLiBSZW1lbWJlciB5b3Ugd2lsbCBuZWVkIHRvIGFkanVzdCB0aGUgYW5jaG9yIHBvaW50cyBvZiB5b3VyIF9uYW1lIGFuZCBkYXRlXyB0ZXh0LCBfbm9ydGggYXJyb3dfIGFuZCBfc2NhbGUgYmFyXyB0byBmaXQgdGhlIGN1cnJlbnQgbWFwIHZpZXcuIEFkZGl0aW9uYWxseSwgdGhlIF90aXRsZV8gYW5kIF9sZWdlbmQgdGV4dF8gc2hvdWxkIGFsc28gcmVmbGVjdCB0aGUgaW5mb3JtYXRpb24gZGVwaWN0ZWQgb24geW91ciBtYXAuDQoNCjxiaWc+PGI+UXVlc3Rpb24gTm8uIDQ8L2I+PC9iaWc+DQo8YmxvY2txdW90ZT4NCldoaWNoIGNvdW50eSBoYWQgdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIHJlcG9ydGVkIHRvcm5hZG9lcz88YnI+DQpUeXBlIGBgYHN1YnNldCh0bl90b3JuYWRvZXMsIHRvcm5hZG9fY291bnQgPT0gbWF4KHRvcm5hZG9fY291bnQpKWBgYCBpbnRvIGEgbmV3IGNvZGUgY2VsbCBvciB1c2UgR29vZ2xlIHRvIHNlYXJjaCBmb3IgYSBjb3VudHkgbWFwIG9mIFRlbm5lc3NlZSB0byBkZXRlcm1pbmUgY291bnR5IGxvY2F0aW9ucyBvbiB5b3VyIG1hcC48YnI+IA0KPHNtYWxsPkhpbnQ6IFJlcGxhY2UgKip0bl90b3JuYWRvZXMqKiBpbiB0aGUgY29kZSBhYm92ZSB3aXRoIHRoZSBvYmplY3QgeW91IGNyZWF0ZWQgYnkgbWVyZ2luZyB0aGUgdG9ybmFkbyBhbmQgY291bnRpZXMgZGF0YXNldHMuPC9zbWFsbD4NCjwvYmxvY2txdW90ZT4NCg0KPC9kZXRhaWxzPg0KDQojIFRoZSBXcml0ZS1VcA0KVGhlIE1vbnRnb21lcnkgQ291bnR5IEVtZXJnZW5jeSBNYW5hZ2VtZW50IEFnZW5jeSBoYXMgYXNrZWQgeW91IHRvIHByb3ZpZGUgYSBtYXAgZGV0YWlsaW5nIHRoZSBudW1iZXIgb2YgcmVwb3J0ZWQgdG9ybmFkb2VzIGluIGVhY2ggVGVubmVzc2VlIGNvdW50eSBvdmVyIHRoZSBwYXN0IHNldmVyYWwgZGVjYWRlcy4gQmFzZWQgb24gdGhlIG1hcCB5b3UgY3JlYXRlIGFib3ZlLCBjb21wbGV0ZSBhIGxhYiB3cml0ZS11cCB0aGF0IGFkZHJlc3NlcyB0aGUgZm9sbG93aW5nIHF1ZXN0aW9uczoNCg0KLSBQcm92aWRlIHRoZSBuYW1lcyBvZiB0aGUgZml2ZSAoNSkgY291bnRpZXMgdGhhdCByZWNvcmRlZCB0aGUgbW9zdCB0b3JuYWRvZXMgZHVyaW5nIHRoYXQgdGltZSBmcmFtZQ0KLSBEZXNjcmliZSB3aGljaCByZWdpb25zIG9mIFRlbm5lc3NlZSBoYWQgdGhlIGZld2VzdCByZXBvcnRlZCB0b3JuYWRvZXMgDQotIEluZm9ybSBNQ0VNQSB3aGljaCBtZXRyb3BvbGl0YW4gcmVnaW9ucyBjb3VsZCBiZSBtb3N0IGltcGFjdGVkIGJ5IGZ1dHVyZSBzZXZlcmUgd2VhdGhlciBldmVudHMNCg0KV2hlbiBjb21wbGV0ZSwgc2VuZCBsaW5rIHRvIHlvdXIgX0NvbGFiIE5vdGVib29rXyB2aWEgZW1haWwuDQo=